一. 概念
LVM是 LogicalVolumeManager(逻辑卷管理)的简写,它由Heinz Mauelshagen在Linux2.4内核上实现。LVM将一个或多个硬盘的分区在逻辑上集合,相当于一个大硬盘来使用,当硬盘的空间不
二. 优点
- 使系统管理员可以更方便的为应用与用户分配存储空间。
- 在LVM管理下的存储卷可以按需要随
版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作! 时改变大小与移除。 - 允许按用户组对存储卷进行管理,可用更直观的名称如development代替物理磁盘名如sda来标识存储卷。
三. LVM基本术语
- 物理存储:物理存储介质指系统的存储设备:硬盘,如:hda1等等,是存储系统最低层的存储单元。
- 物理卷(pv):指硬盘分区或从逻辑上与磁盘分区具有同样功能的设备(如RAID),是LVM的基本存储逻辑块,包含了物理介质没有的LVM相关管理参数。
- 卷组(vg):指由一个或多个物理卷组成的逻辑上的”物理硬盘”,可以在卷组上创建一个或多个“LVM分区”(逻辑卷)。
- 逻辑卷(lv):逻辑卷类似于非LVM系统中的硬盘分区,在逻辑卷之上可以建立文件系统(比如/home或者/usr等)。
- PE(physical extent):PE指每一个物理卷所划分的基本单元,默认大小为4M,具有唯一编号,是可以被LVM寻址的最小单元。
- LE(physical extent):LE指每一个逻辑卷所划分的基本单元,大小与PE相同。
四. LVM基本使用
1.创建分区
使用分区工具(如fdisk等)创建LVM分区,却将分区标识为LVM的分区类型8e。
[[email protected] ~]# fdisk -l
……
Device Boot Start End Blocks Id System
/dev/sdb1 2048 20971519 10484736 5 Extended
/dev/sdb5 4096 2101247 1048576 8e Linux LVM
/dev/sdb6 2103296 4200447 1048576 8e Linux LVM
2.创建PV
[[email protected] ~]# pvcreate /dev/sdb5 #将每个分区转换成PV
Physical volume "/dev/sdb5" successfully created
[[email protected] ~]# pvcreate /dev/sdb6
Physical volume "/dev/sdb6" successfully created
查看验证
[[email protected] ~]# pvdisplay
……
3.创建VG
[[email protected] ~]# vgcreate -s 16m vg01 /dev/sdb5 /dev/sdb6 /dev/sdb7
#创建名称为vg01的VG组,且PE修改为16m
Volume group "vg01" successfully created
查看验证
略
注意:LVM 默认使用 4MB 的 PE 区块,即可默认的 LVM VG 会有 4M*65534/(1024M/G)=256G
4.创建LV
[[email protected] ~]# lvcreate -L 1g -n lv01 vg01
Logical volume "lv01" created.
查看验证
[[email protected] ~]# lvdisplay
5.格式化
[[email protected] ~]# mkfs.xfs /dev/vg01/lv01 #格式化为相应的格式
meta-data=/dev/vg01/lv01 isize=256 agcount=4, agsize=65536 blks
= sectsz=512 attr=2, projid32bit=1
= crc=0 finobt=0
data = bsize=4096 blocks=262144, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=0
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
6.挂载
[[email protected] ~]# mkdir /root/mylv01 #创建用于挂载的目录
[[email protected] ~]# mount /dev/vg01/lv01 /root/mylv01/ #挂载至相应目录
[[email protected] ~]# df -h #查看验证
Filesystem Size Used Avail Use% Mounted on
……
/dev/mapper/vg01-lv01 1014M 33M 982M 4% /root/mylv01
开机挂载
[[email protected] ~]# vi /etc/fstab
/dev/vg01/lv01 /root/mylv01 xfs defaults 0 0 #修改为开机挂载
7.创建LVM分区
首先,挂载虚拟硬
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 99G 0 part
├─centos-root 253:0 0 50G 0 lvm /
├─centos-swap 253:1 0 9.8G 0 lvm [SWAP]
└─centos-home 253:2 0 39.2G 0 lvm /home
sdb 8:16 0 1T 0 disk
sdc 8:32 0 1T 0 disk
sr0 11:0 1 1024M 0 rom
// 创建物理卷
$ sudo pvcreate /dev/sdb
Physical volume "/dev/sdb" successfully created.
// 创建卷组
$ sudo vgcreate VG1 /dev/sdb
Volume group "VG1" successfully created
// 查看卷组剩多少PE
$ sudo vgdisplay
...
--- Volume group ---
VG Name VG1
System ID
Format lvm2
Metadata Areas 2
Metadata Sequence No 7
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 1
Open LV 0
Max PV 0
Cur PV 2
Act PV 2
VG Size <2.00 TiB
PE Size 4.00 MiB
Total PE 524286
Alloc PE / Size 262143 / <1024.00 GiB
Free PE / Size 262143 / <1024.00 GiB //剩余空间大小
VG UUID DYPyVN-9ssj-pLxN-bksi-9U0V-m2wQ-aQ3IPe
...
// 将所有剩余空间创建为逻辑卷
$ sudo lvcreate -l 262143 -n MyLvm0 VG1
Logical volume "MyLvm0" created.
// 创建完成
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 99G 0 part
├─centos-root 253:0 0 50G 0 lvm /
├─centos-swap 253:1 0 9.8G 0 lvm [SWAP]
└─centos-home 253:2 0 39.2G 0 lvm /home
sdb 8:16 0 1T 0 disk
└─VG1-MyLvm0 253:3 0 1024G 0 lvm // 所创建的LVM逻辑卷
sdc 8:32 0 1T 0 disk
sr0 11:0 1 1024M 0 rom
8.扩展LVM分区
上面使用了一块1T虚拟硬盘,下面将另外一块虚拟硬盘添加到刚才的逻辑卷中,实现扩展。
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 99G 0 part
├─centos-root 253:0 0 50G 0 lvm /
├─centos-swap 253:1 0 9.8G 0 lvm [SWAP]
└─centos-home 253:2 0 39.2G 0 lvm /home
sdb 8:16 0 1T 0 disk
└─VG1-MyLvm0 253:3 0 1024G 0 lvm // 需要扩展的LVM逻辑卷
sdc 8:32 0 1T 0 disk // 额外的空间
sr0 11:0 1 1024M 0 rom
// 创建物理卷
$ sudo pvcreate /dev/sdc
Physical volume "/dev/sdc" successfully created.
// 将它加入到卷组
$ sudo vgextend VG1 /dev/sdc
Volume group "VG1" successfully extended
// 扩展逻辑卷MyLvm0
$ sudo lvextend -l +262142 /dev/VG1/MyLvm0
Size of logical volume VG1/MyLvm0 changed from 1.00 TiB (262144 extents) to <2.00 TiB (524286 extents).
Logical volume VG1/MyLvm0 successfully resized.
// 成功扩展
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 99G 0 part
├─centos-root 253:0 0 50G 0 lvm /
├─centos-swap 253:1 0 9.8G 0 lvm [SWAP]
└─centos-home 253:2 0 39.2G 0 lvm /home
sdb 8:16 0 1T 0 disk
└─VG1-MyLvm0 253:3 0 2T 0 lvm
sdc 8:32 0 1T 0 disk
└─VG1-MyLvm0 253:3 0 2T 0 lvm
sr0 11:0 1 1024M 0 rom
五. LVM创建虚拟磁盘阵列
1.创建磁盘分区
目前做LVM分区比较推荐的工具还是fdisk,不是说parted不能做,而是fdisk可能更加方便一点。流程如下:
# fdisk /dev/nvme0n1
Command (m for help): n ## 新建
Command action
e extended
p primary partition (1-4)
p ## 主分区
Partition number (1-4): 1 ## 分区号
First cylinder (2048-543352123, default 2048): ## 回车用默认的1
Last cylinder, +cylinders or +size{K,M,G} (2048-543352123, default 543352123): ## 回车默认大小大小
Command (m for help): t ## 改变toggle类型
Selected partition 1
Hex code (type L to list codes): 8e ## LVM 的分区代码8e
Changed system type of partition 1 to 8e (Linux LVM)
2.创建物理卷PV
在分区完成之后需要做的就是创建物理卷,直接将刚才创建的分区进行
pvcreate:
# pvcreate /dev/nvme0n1p1
3.创建虚拟卷VG
在创建玩物理卷之后,需要对该磁盘进行虚拟卷的创建。需要注意的是一个虚拟卷可以由多个物理卷构成。例如:
# vgcreate nvme /dev/nvme0n1p1 /dev/nvme1n1p1 /dev/nvme2n1p1
该命令的意义就在于创建一个叫做nvme的虚拟卷,由/dev/nvme0n1p1、 /dev/nvme1n1p1、 /dev/nvme2n1p1三个做了pv的分区构成
4.创建逻辑卷LG
到了这一步,基本上LVM的创建已经到了尾声了,最后一步就是从虚拟卷中创建一个逻辑卷。如下:
# lvcreate -L 2.91T -n data nvme
这条命令的意思为从虚拟卷nvme中创建一个2.91T的逻辑卷作为lvm分区并命名为data,如果想一次性全部用完所有的容量,也可以这样:
# lvcreate -l -n data nvme
此时在linux的/dev/文件夹下面我们可以看到有/nvme/data的文件结构。
5.挂载并更新文件
在创建完lvm分区后,我们需要将分区挂在到系统中的路径中。假设需要挂载的路径是/data。
# mkdir /data ##创建该路径
# mount /dev/mapper/nvme-data /data ##需要注意的时候这里推荐使用/dev/mapper/nvme-data作为挂载的设备路径,而不是/dev/nvme/data
之后通过blkid命令获取这个新的lvm分区的UUID,然后更新到/etc/fstab中就可以了
八. Replication+LVM Snapsho
基于快照和复制技术的结合
当主库发生误操作时,只需要恢复备库上的快照,然后再根据binlog执行point-in-time的恢复即可
下面假定一个场景:
主从架构,没有延迟,某DBA误操作:drop database
接下来我们按照以上场景进行备份恢复模拟测试
1.主库准备测试数据
mysql> create database cnfol;
Query OK, 1 row affected (0.00 sec)
mysql> create table cnfol.t (id int primary key);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into cnfol.t select 1;
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> insert into cnfol.t select 2;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
到备库确认:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| cnfol |
| mysql |
| test |
+--------------------+
4 rows in set (0.00 sec)
mysql> select * from cnfol.t;
+----+
| id |
+----+
| 1 |
| 2 |
+----+
2 rows in set (0.00 sec)
2.备库设置全局读锁
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)
3.备库所在分区创建快照
[[email protected] ~]# lvcreate --size 1G --snapshot --name backup_mysql /dev/vg/mysql
Logical volume "backup_mysql" created
[[email protected] ~]# lvs
LV VG Attr LSize Origin Snap% Move Log Copy% Convert
backup_mysql vg swi-a- 1.00G mysql 0.00
mysql vg owi-ao 2.00G
4.备库获取二进制日志坐标
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 727 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
5.备库设置全局解锁
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
6.挂载快照
[[email protected] ~]# mount /dev/vg/backup_mysql /mnt/backup
[[email protected] ~]# cd /mnt/backup/mysql/data/cnfol/ && ls -alh
总计 32K
drwx------ 2 mysql dba 4.0K 10-14 09:57 .
drwx------ 5 mysql dba 4.0K 10-14 09:57 ..
-rw-rw---- 1 mysql dba 61 10-14 09:57 db.opt
-rw-rw---- 1 mysql dba 8.4K 10-14 09:57 t.frm
-rw-rw---- 1 mysql dba 14 10-14 09:57 t.MYD
-rw-rw---- 1 mysql dba 2.0K 10-14 10:06 t.MYI
7.主库某无经验DBA误操作
mysql> drop database cnfol;
Query OK, 1 row affected (0.05 sec)
记录下此时时间:2013-10-14 10:17:10 备库确认是否存在库cnfol:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| test |
+--------------------+
3 rows in set (0.01 sec)
8.备份快照
[[email protected] backup]# pwd
/mnt/backup
[r[email protected] backup]# tar -jcv -f /mnt/snapshot/mysql.tar.bz2 *
这里做备份的原因有2点
- 其一,昂贵的IO,因为磁头要在快照区和系统区来回跑
- 其二,快照区空间不足,因为是COW原理
9.删除快照
[[email protected] ~]# umount /mnt/backup
[[email protected] ~]# lvremove --force /dev/vg/backup_mysql
Logical volume "backup_mysql" successfully removed
10.格式化备库所在分区
[[email protected] ~]$ mysqladmin -uroot -poracle shutdown
131014 10:32:40 mysqld_safe mysqld from pid file /mnt/lvm/mysql/data/localhost.localdomain.pid ended
[1]+ Done mysqld_safe
[[email protected] ~]# umount /mnt/lvm
[[email protected] ~]# mkfs -t ext3 /dev/vg/mysql
[[email protected] ~]# mount /dev/vg/mysql /mnt/lvm
[[email protected] ~]# lvs
LV VG Attr LSize Origin Snap% Move Log Copy% Convert
mysql vg -wi-ao 2.00G
[[email protected] ~]# vgs
VG #PV #LV #SN Attr VSize VFree
vg 4 1 0 wz--n- 3.81G 1.81G
11.解压缩快照到备库所在分区
# tar -jxv -f /mnt/snapshot/mysql.tar.bz2 -C /mnt/lvm/
[[email protected] lvm]# pwd
/mnt/lvm
[[email protected] lvm]# ls
lost+found mysql
12.启动MySQL
13.利用binlog恢复数据
利用binlog执行point-in-time恢复
[[email protected] ~]$ mysqlbinlog --stop-datetime="2013-10-14 10:17:10" /mnt/lvm/mysql/data/mysql-bin.000003 | mysql -uroot -poracle
14.确认数据
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| cnfol |
| mysql |
| test |
+--------------------+
4 rows in set (0.00 sec)
mysql> select * from cnfol.t;
+----+
| id |
+----+
| 1 |
| 2 |
+----+
2 rows in set (0.00 sec)