MySQL备份还原方法2----LVM
2.LVM 备份
LVM(Logical Volume Manager,逻辑卷管理器)是 Linux 环境下强大的存储管理工具,其备份主要基于 快照(Snapshot) 功能实现热备份(在线备份,即系统运行时备份),无需卸载文件系统。
2.1准备新磁盘 & 逻辑卷
不要用我们的系统磁盘,更安全。
在虚拟机去添加一块新磁盘
[root@bogon ~]# lsblkNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda8:0010G0disk#新加的磁盘sr011:0112.7G0rom /mnt nvme0n1259:00200G0disk ├─nvme0n1p1259:10600M0part /boot/efi ├─nvme0n1p2259:201G0part /boot └─nvme0n1p3259:30198.4G0part ├─rhel-root253:0070G0lvm / ├─rhel-swap253:102G0lvm └─rhel-home253:20126.4G0lvm /home#创建卷组,物理卷会自动创建[root@bogon ~]# vgcreate mysql /dev/sdaVolume group"mysql"successfully created#创建逻辑卷[root@bogon ~]# lvcreate -n lv_mysql -L 6G mysqlWARNING: xfs signature detected on /dev/mysql/lv_mysql at offset0. Wipe it?[y/n]: y Wiping xfs signature on /dev/mysql/lv_mysql. Logical volume"lv_mysql"created.#格式化[root@bogon ~]# mkfs.xfs /dev/mysql/lv_mysql[root@bogon ~]# lsblkNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda8:0010G0disk └─mysql-lv_mysql253:306G0lvm#这里sr011:0112.7G0rom /mnt nvme0n1259:00200G0disk ├─nvme0n1p1259:10600M0part /boot/efi ├─nvme0n1p2259:201G0part /boot └─nvme0n1p3259:30198.4G0part ├─rhel-root253:0070G0lvm / ├─rhel-swap253:102G0lvm └─rhel-home253:20126.4G0lvm /home#挂载2.2数据迁移
[root@bogon ~]# systemctl stop mysqld[root@bogon ~]# tar -zcf /tmp/mysql.tar.gz /var/lib/mysql/*[root@bogon ~]# tar -tf /tmp/mysql.tar.gz #可以查看压缩包[root@bogon ~]# mount /dev/mysql/lv_mysql /var/lib/mysql[root@bogon ~]#[root@bogon ~]# tar -zxf /tmp/mysql.tar.gz -C /[root@bogon ~]# ll -d /var/lib/mysqldrwxr-xr-x.9root root4096Mar3116:13 /var/lib/mysql[root@bogon ~]# ll /var/lib/mysqltotal90192-rw-r-----.1mysql mysql56Mar2811:53 auto.cnf -rw-r-----.1mysql mysql4487Mar2812:01 binlog.000001 -rw-r-----.1mysql mysql181Mar2814:21 binlog.000002 。。。。。。[root@bogon ~]# chown -R mysql: /var/lib/mysql[root@bogon ~]# systemctl start mysqld1.解压那一步不要指定解压到/var/lib/mysql,因为压缩时,这个目录也同样压缩了。否则解压出来是/var/lib/mysql/var/lib/mysql/。。。
2.一定要先压缩再挂载最后解压
- 直接挂载:新卷覆盖了目录,里面的数据是新卷自带的(可能是空的、旧的、或别的)
- 备份再解压:先把旧数据打包保存,挂载新卷后,再把旧数据还原进去
3.在压缩前先暂停服务。停服务是为了保证数据一致性,避免备份/迁移过程中数据损坏。
4.关于权限问题,不仅要关注目录里面文件权限,也要关注目录本身的权限
2.3数据备份
大概步骤:
1)锁表 flush table with read lock
2)查看position号并记录,便于后期恢复 show master status
3)创建snapshot快照 create snapshop
4)解表 unlock tables
5)挂载snapshot
6)拷贝snapshot数据,进行备份。备份整个数据库之前,要关闭mysql服务(保护ibdata1文件)
7)卸载
8)移除快照
这里可以用shell脚本来做
[root@bogon ~]# cat bak_mysql.sh#!/bin/bashbak_dir=/bak/$(date+%F)[-d${bak_dir}]||mkdir-p${bak_dir}echo"flush tables with read lock; system lvcreate -s -n lv_mysql_s -L 500M /dev/mysql/lv_mysql; unlock tables;"|mysql-uroot-p123456[-d/media/mysql/]||mkdir-p/media/mysqlmount-txfs-onouuid /dev/mysql/lv_mysql_s /media/mysql#用 rsync 把快照里的数据同步到备份目录rsync-az/media/mysql/${bak_dir}if[$?-eq0];thenumount/media/mysql/&&lvremove-f/dev/mysql/lv_mysql_s&>/dev/nullfi[root@bogon ~]# bash bak_mysql.sh[root@bogon ~]# ls /bak/2026-03-31auto.cnf ca.pem ibdata1 mysql.sock school binlog.000001 client-cert.pem'#innodb_redo'mysql.sock.lock server-cert.pem binlog.000002 client-key.pem'#innodb_temp'mysql_upgrade_history server-key.pem binlog.000003'#ib_16384_0.dblwr'mydb performance_schema sys binlog.index'#ib_16384_1.dblwr'mysql private_key.pem undo_001 ca-key.pem ib_buffer_pool mysql.ibd public_key.pem undo_002rsync -az /media/mysql/ ${bak_dir}
这一步相当于rsync -az /media/mysql/ /bak/2026-03-31
/media/mysql/是/dev/mysql/lv_mysql_s快照中的数据,即逻辑卷的数据,即/var/lib/mysql的数据
用快照而不是直接挂载逻辑卷,主要是为了实现一致性备份。
为什么要弄一个/media/mysql,而不是直接将快照挂载到/bak/2026XXX…???
/bak/2026XXX是文件系统路径,不是挂载点简单类比:就像你要复制光盘里的文件到硬盘,需要先把光盘挂载到某个空目录,复制到目标文件夹,而不是直接把光盘挂载到目标文件夹。
但是我的/bak/2026XXX本来也是空的,专门用一个中转的区别在?这么做优点?
- 防止意外覆盖
如果/bak/2026XXX不小心非空了,直接挂载会隐藏原有文件。用固定空目录挂载,安全。- 脚本简单可靠
挂载点固定(/media/mysql),备份目录可变(/bak/日期)。逻辑解耦,不容易写错路径。- 支持并发备份
可以同时挂载多个快照到不同目录(/media/mysql1、/media/mysql2),同时备份到不同/bak/子目录。
2.4数据还原 & 验证
#模拟数据被破坏mysql>drop database mydb;Query OK,1row affected(0.01sec)#停止mysqld服务[root@bogon ~]# systemctl stop mysqld#改数据目录为之前备份的目录[root@bogon ~]# vim /etc/my.cnf[root@bogon ~]# cat /etc/my.cnf | grep datadir=#datadir=/var/lib/mysqldatadir=/bak/2026-03-31#检查该目录本身及下面文件都是mysql用户[root@bogon ~]# ll -d /bak/2026-03-31drwxr-xr-x.9mysql mysql4096Mar3116:41 /bak/2026-03-31[root@bogon ~]# ll /bak/2026-03-31total90204-rw-r-----.1mysql mysql56Mar2811:53 auto.cnf -rw-r-----.1mysql mysql4487Mar2812:01 binlog.000001 。。。。。。#重启[root@bogon ~]# systemctl restart mysqld#检验mysql>show databases;+--------------------+|Database|+--------------------+|information_schema||mydb|#又回来了|mysql||performance_schema||school||sys|+--------------------+流程(原理):
删除数据库后,这个删除的日志记录在/var/lib/mysql下面(/etc/my.cnf中默认的数据路径)
这时候我们要停止服务,进入/etc/my.cnf中,修改datadir为删除前备份的目录
再重启,就相当于是用的删除前的日志,因此数据库恢复(存在)
