当前位置: 首页 > news >正文

MySQL之备份与恢复(六)

备份与恢复

文件系统快照

先决条件和配置

创建一个快照的消耗几乎微不足道,但还是需要确保系统配置可以让你获取在备份瞬间的所有需要的文件的一致性副本。首先,确保系统满足下面这些条件。

  • 1.所有的InnoDB文件(InnoDB的表空间文件和InnoDB的事务日志)必须时在单个逻辑卷(分区)。你需要绝对的时间点一致性,LVM不能为多于一个卷做某个时间点一致的快照。(这是LVM的一个限制;其他一些系统没有这个问题)
  • 2.如果需要备份表定义,MySQL数据目录必须在相同的逻辑卷中。如果使用另外一种方法来备份表的帝国一,例如只备份Schema到版本控制系统中,就不需要担心这个问题
  • 3.必须在卷组中有足够的空闲空间来创建快照。需要多少取决于负载。当配置系统时,应该留一些未分配的空间以便后面做快照。

LVM有卷组的概念,它包含一个或多个逻辑卷。可以按照如下的方式查看系统中的卷组:

vgs
VG:vg
#PV:1
#LV:4
#SN:0
Attr:wz--n-
VSize:534.18G
VFree:249.18G

输出显示了一个分布在一个物理卷上的卷组,它有四个逻辑卷,大概有250GB空间空闲。入股哦需要,可用vgdisplay命令产生更详细的输出。现在让我们看下系统上的逻辑卷

lvs
LV:home
VG:vg
Attr:-wi-ao
LSize:40.00G
Origin Snap%:
Move Log Copy%:LV:mysql
VG:vg
Attr:-wi-ao
LSize:225.00G
Origin Snap%:
Move Log Copy%:LV:tmp
VG:vg
Attr:-wi-ao
LSize:10.00G
Origin Snap%:
Move Log Copy%:LV:var
VG:vg
Attr:-wi-ao
LSize:10.00G
Origin Snap%:
Move Log Copy%:

创建、挂载和删除LVM快照

一条命令就能创建快照。只需要决定快照存放的未知和分配给写时复制的空间大小即可。不要纠结于是否适用比想象中的需求更多的空间。LVM不会马上使用完所有指定的空格键,只是为后续适用预留而已。因此多预留一点空间并没有坏处,除非你必须同时为其他快照预留空间。让我们来练习创建一个快照。我们给它16GB的写时复制空间,名字为backup_mysql.

lvcreate --size 16G --snapshot --name backup_mysql /dev/vg/mysq

这里特意命名为backup_mysql卷而不是mysql_backup,是为了避免Tab键自动补全造成误会。这有助于避免因为Tab键自动补全导致突然误删除mysql卷组的可能。我们可以适用lvs看看新创建的卷的状态。快照的属性与原设备不同,而且该输出还显示了一点额外的信息:原始卷组和分配了16GB的写时复制空间目前已经使用了多少。备份对此进行监控是个非常好的主意,可以知道是否会因为设备写满而备份失败。可以交互地监控设备的状态,或使用诸如Nagios这样的监控系统。

wathc 'lvs | grep backup'

从前面mount的输出可以看到,mysql卷包含一个文件系统。这意味着快照也同样如此,可以像其他文件系统一样挂载。

mkdir /tmp/backup
mount /dev/mapper/vg-backup_mysql /tmp/backup
ls -l /tmp/backup/mysql

这里只是为了联系,因此我们卸载这个快照并用lvremove命令将其删除

umount /tmp/backup
rmdir /tmp/backup
lvremove --force /dev/vg/backup_mysql

用于在线备份的LVM快照

在这里插入图片描述

现在已经知道如何创建、加载和删除快照,可以使用它们来进行备份了。首先看一下如何在不停止MySQL服务的情况下备份InnoDB数据库,这里需要使用一个全局的读锁。连接MySQL服务器并使用一个全局读锁将表刷到磁盘上,然后获取二进制日志的位置:

mysql>FLUSH TABLES WITH READ LOCK; SHOW MASTER STATUS;

记录SHOW MASTER STATUS的输出,确保到MySQL的连接处于打开状态,以使读锁不被释放。然后获取LVM的快照并立刻释放该读锁,可以使用UNLOCK TABLES或直接关闭连接来释放锁。最后,加载快照并赋值文件到备份位置。这种方法最主要的问题是,获取读锁可能需要一点时间,特别时当有许多长时间运行的查询时。当连接等待全局读锁时,所有的查询都将被阻塞,并且不可预测这会持续多久。

文件系统快照和InnoDB

即使锁住所有的表,InnoDB的后台线程仍会继续工作,因此,即使在创建快照时,仍然可以往文件中写入。并且,由于InnoDB没有执行关闭操作。如果服务器意外断电,快照中InnoDB的文件会和服务器意外掉电后文件的遭遇一样。这不是什么问题,因为InnoDB是个ACID系统。任何时刻(例如快照时),每隔提交的事务要么在InnoDB数据文件中要么在日志文件中。在还原快照后启动MySQL时,InnoDB将运行恢复进程,就像服务器断过电一样。它会查找事务日志中任何提交但没有应用到数据文件中的事务然后应用,因此不会丢失任何事务。这正是要强制InnoDB数据文件和日志文件在一起快照的原因。这也是在备份后需要测试的原因。启动一个MySQL实例,把它指向一个新备份,让InnoDB执行崩溃恢复过程,然后检测所有的表。通过这种方法,就不会备份损坏了却还不知道(文件可能由于任何原因损坏)。这么做的另外一个好处是,维拉i需要从备份中还原时会更快,因为已经在备份上运行过一遍恢复程序了。甚至还可以在将快照复制到备份目的地之前,直接在快照上做上面的操作,但增加一点点额外开销。所以需要确保这是计划内的操作

使用LVM快照无所InnoDB备份

在这里插入图片描述

无锁备份只有一点不同。区别是不需要执行FLUSH TABLES WITH READ LOCK.这意味着不能保证MyISAM文件在磁盘上一致,如果只使用InnoDB,这就不是问题。mysql系统数据库中依然有部分MyISAM表,但如果是典型的工作负载,在快照时这些表不太可能发生改变。如果你认为mysql系统表可能会变更,那么可以锁住并刷新这些表。一般不会对这些表有长时间运行的查询,所以通常会很快:

mysql> LOCK TABLES mysql.user READ, mysql.db READ;
mysql> FLUSH TABLES mysql.user, mysql.db;

由于没有用全局读锁,因此不会从SHOW MASTER STATUS 中获取到任何有用的信息。尽管如此,基于快照启动MySQL(来验证备份的完整性)时,也将会在日志文件中看到像下面的内容:

InnoDB: Doing recovery: scanned up to log sequence number 0 40817239
InnoDB: Starting an apply batch of log records to the database...
InnoDB:Progress in percents: 3 4 5 6 ..  [omitted] ... 97 98 99
InnoDB:Apply batch completed
InnoDB:Last MySQL binlog file position 0 3304937,file name /var/log/mysql/mysql-bin.000001
070928 14:08:42 InnoDB:Started; log sequence number 0 40817239

InnoDB记录了MySQL已经恢复得时间点对应的二进制日志位置,这个二进制日志位置可以用来做基于时间点的恢复。使用快照进行无锁备份的方法在MySQL5.0或更新版本中有变动。这些MySQL版本使用XA来协调InnoDB和二进制日志。如果还原到一个与备份时server_id不同的服务器,服务器在准备事务阶段可能发现这是从另外一个与自己不同ID的服务器来的。在这种情况下,服务器会变得困惑,恢复事务时可能会卡在PREPARED状态。这种情况很少发生,但是存在可能性。这也是只有经过验证才可以说备份成功的原因。有些备份也许是不能恢复的。如果时在备库上获取快照,InnoDB恢复时还会打印如下几行日志:

InnoDB:In a MySQL replica the last master binlog file
InnoDB:position 0 115, file name mysql-bin.001717

输出显示了InnoDB已经恢复了基于主库的二进制位置(相对于备库二进制日志位置),这对基于备库备份或基于其他备库克隆备库来说非常有用

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【Git 学习笔记】第二章 Git 的配置(上)
  • 使用ChatGPT写论文,只需四步突破论文写作瓶颈!
  • 昆虫学(书籍学习资料)
  • 基于深度学习的图像背景剔除
  • QML-Grid和OpacityMask
  • [go-zero] 简单微服务调用
  • 华为交换机 LACP协议
  • 实在智能对话钉钉:宜搭+实在Agent,AI时代的工作方式
  • C++中的左值、右值介绍
  • PEFT - 安装及简单使用
  • [算法]——堆排序(C语言实现)
  • MUNIK解读ISO26262--系统架构
  • 网络编程:UDP编程笔记
  • (一)Docker基本介绍
  • 【PYG】dataloader和densedataloader
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • 10个确保微服务与容器安全的最佳实践
  • ES10 特性的完整指南
  • Java面向对象及其三大特征
  • Python学习之路16-使用API
  • Vue 2.3、2.4 知识点小结
  • 阿里研究院入选中国企业智库系统影响力榜
  • 阿里云购买磁盘后挂载
  • 不上全站https的网站你们就等着被恶心死吧
  • 从0实现一个tiny react(三)生命周期
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 开源SQL-on-Hadoop系统一览
  • 每天10道Java面试题,跟我走,offer有!
  • 想写好前端,先练好内功
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • 积累各种好的链接
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • #pragam once 和 #ifndef 预编译头
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • (007)XHTML文档之标题——h1~h6
  • (ros//EnvironmentVariables)ros环境变量
  • (solr系列:一)使用tomcat部署solr服务
  • (待修改)PyG安装步骤
  • (转)ObjectiveC 深浅拷贝学习
  • *算法训练(leetcode)第四十天 | 647. 回文子串、516. 最长回文子序列
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .net的socket示例
  • .NET命令行(CLI)常用命令
  • .ui文件相关
  • @ModelAttribute注解使用
  • @RequestMapping用法详解
  • [ 代码审计篇 ] 代码审计案例详解(一) SQL注入代码审计案例
  • [000-01-030].Zookeeper学习大纲
  • [10] CUDA程序性能的提升 与 流
  • [ABC275A] Find Takahashi 题解
  • [Armbian] 部署Docker版Home Assistent,安装HACS并连接米家设备
  • [BFS广搜]迷阵