备份数据库指南

“哦,任何庇护所都无法承受流星撞击。但是您和所有人一样,都有储备,所以请不要担心。



斯坦尼斯拉夫·莱姆(Stanislav Lem),《提温依云的星际日记》


备份是指将数据副本保留在主存储位置之外的某个位置。







备份的主要目的是在丢失数据后恢复数据。在这方面,我们经常听到,如果您有数据库的副本,则始终可以从数据库中还原数据,并且不需要备份。实际上,备份使您能够解决至少三个使用副本无法解决的任务,并且如果没有备份就无法初始化副本。



首先,备份使您可以在发生逻辑错误后恢复数据。例如,一位会计师删除了一组交易,或者DBA破坏了一个表空间。从数据库的角度来看,这两种操作都是绝对合法的,并且复制过程将在副本数据库中复制它们。



其次,现代的DBMS是非常可靠的软件系统,但是偶尔会损坏数据库的内部结构,此后将丢失对数据的访问。特别令人反感的是,这种违反通常发生在高负载或安装某种更新时。但是高负载和定期更新都表明该数据库不是测试数据库,并且其中存储的数据很有价值。



最后,解决该问题需要备份副本的第三项任务是克隆数据库,例如,出于测试目的。



数据库备份以某种方式基于以下两个原理之一:



  • 提取数据并随后以任意格式保存;
  • 数据库文件快照和保存日志。


让我们仔细看看这些原理和实现它们的工具。



上载资料



任何DBMS随附的实用程序集都必须具有用于上载和下载数据的工具。数据以文本格式或特定于特定DBMS的二进制格式存储。下表列出了这些工具:



二进制格式 文字格式

甲骨文 DataPump导出/ DataPump导入

导出/导入
SQL *加号/ SQL *加载程序
PostgreSQL的 pg_dump,pg_dumpall / pg_restore pg_dump,pg_dumpall / psql
Microsoft SQL服务器 bcp bcp
DB2 卸载/加载 卸载/加载
的MySQL mysqldump,mysqlpump / mysql,mysqlimport
MongoDB mongodump / mongorestore mongoexport / mongoimport
卡桑德拉 nodetool快照/ sstableloader cqlsh


文本格式是好的,因为它可以由外部程序编辑甚至创建,而二进制格式又是好的,因为它允许您由于并行加载而快速卸载和加载数据,并节省了格式转换的资源。



尽管下载数据的想法很简单明了,但这种方法很少用于备份已加载的工业基础。以下是卸载不适合完全备份的原因:



  • 卸载过程在源系统上造成了很大的负担;
  • 卸载要花费大量时间-卸载完成时,它将变得无关紧要;
  • 在高负载下几乎不可能对整个数据库进行一致的卸载,因为DBMS在卸载开始时被迫保留其状态的快照。自上载开始以来已提交的事务越多,快照量就越大(PostgreSQL中数据的不相关副本,Oracle中的撤消空间,Microsoft SQL Server中的tempdb等);
  • 卸载保留数据的逻辑结构,但不保留其物理结构-表,索引等的物理存储参数;在引导时重建索引可能需要很长时间。


尽管如此,卸载仍具有以下优点:



  • 高选择性:您可以卸载单个表,单个字段,甚至单个行;
  • 可以将上传的数据加载到另一个版本的数据库中,如果以文本格式上传,则可以加载到另一个数据库中。


因此,卸载主要用于诸如备份小表(例如目录)或在应用程序的下一版本中分发数据集之类的任务。



备份数据库的最常用方法是复制数据库文件。



“冷”保存数据库文件



一个明显的想法是停止数据库并复制其所有文件。这称为冷备份。该方法非常可靠且简单,但是有两个明显的缺点:



  • 从冷备份中,您只能还原关闭时的数据库状态;数据库重新启动后进行的事务将不包括在“冷”备份中;
  • 并非每个数据库都有一个技术窗口可以停止数据库。


如果您对冷备份感到满意,请记住



  • «» . , «» , . , Oracle online redo, , , . PostgreSQL , , .
  • , . , «» .


«»



大多数现代数据库备份都是通过复制数据库文件而不停止数据库来执行的。这里有几个问题:



  • 在复制开始时,数据库的内容可能与文件的内容不一致,因为某些信息在高速缓存中并且尚未写入磁盘。
  • 复制期间,数据库的内容可能会更改。如果使用可变数据结构,则文件的内容会更改,而使用不可变结构时,文件集也会更改:出现新文件,删除旧文件。
  • 由于将数据写入数据库和读取数据库文件不会以任何方式同步,因此备份程序可能会读取错误的页面,其中一半来自旧版本的页面,另一半来自新版本的页面。


为了使备份一致,每个DBMS都有一个命令来通知备份过程已开始。从语法上看,此命令可能看起来有所不同:



  • 在Oracle中,它是一个单独的命令ALTER DATABASE / TABLESPACE BEGIN BACKUP;
  • 在PostgreSQL中,pg_start_backup()函数;
  • 在Microsoft SQL Server和DB2上,在BACKUP DATABASE命令期间隐式进行了备份准备;
  • 在MySQL Enterprise,Percoba Server,Cassandra和MongoDB中,准备工作由外部实用程序隐式执行-分别为mysqlbackup,Percona XtraBackup,OpsCenter和Ops Manager。


尽管在语法上有所不同,但准备备份的过程看起来相同。



这就是在具有可变磁盘结构的DBMS中,即在所有传统磁盘关系系统中,备份准备工作的样子:



  1. 记住备份开始的那一刻;从现在开始,备份将必须包含数据库日志。
  2. 执行检查点,即,直到时间点为止在数据页中发生的所有更改都将刷新到磁盘。这样可以确保在恢复期间开始备份之前不需要任何日志。
  3. : , , , . , . , . , , .
  4. , , . , , .


完成上述所有过程之后,您可以使用操作系统工具cp,rsync和其他工具复制数据文件。启用备份模式会降低数据库的性能:首先,日志量会增加;其次,如果突然在备份模式下发生故障,由于数据文件头不会更新,因此恢复将花费更长的时间。备份越早完成,对数据库越好,因此适合使用诸如文件系统快照或磁盘阵列中的镜像中断(BCV)之类的工具。一些DBMS(Oracle,PostgreSQL)使管理员有机会独立选择复制方法,其他(Microsoft SQL Server)提供了用于将本机备份实用程序与文件系统或存储引擎集成的接口。



备份完成后,您需要将数据库恢复到正常状态。在Oracle中,这是通过ALTER DATABASE / TABLESPACE END BACKUP命令,在PostgreSQL中,通过调用pg_stop_backup()函数以及在其他数据库中,通过相应命令的内部例程或外部服务来完成的。



备份过程的时间表如下所示:







  • 准备备份(开始备份)需要时间,有时会花费很多时间。即使使用镜像卷或快照文件系统,备份过程也不会立即进行。
  • 从备份准备工作开始到数据库恢复到正常状态结束之间,都必须保存日志和数据文件。
  • 您可以在数据库恢复到正常状态时从此备份恢复无法恢复到较早的时刻。


对于使用不可变数据结构(快照,LSM树)的数据库,情况更加容易。备份准备工作包括以下步骤:



  1. 来自内存的数据被刷新到磁盘。
  2. 记录备份中包含的文件列表。在备份过程结束之前,即使不再需要这些文件,数据库也禁止删除它们。


收到有关备份即将结束的信号时,具有不变结构的数据库可以再次删除不必要的文件。



点恢复



通过备份,您可以恢复从备份模式返回的命令完成时的数据库状态。但是,随时可能发生需要恢复的灾难。将数据库状态恢复到任意时刻的任务称为时间点恢复。



为此,您应该从备份完成那一刻起保存数据库日志,并在还原过程中继续将日志应用于还原的副本。从副本末尾的备份副本还原数据库后,可以保证数据库状态(文件和缓存页面)是正确的,因此不需要特殊的日志记录模式。通过将日志应用到所需的时刻,您可以随时获取数据库的状态。



如果还原备份的速度仅受磁盘带宽限制,则应用日志的速度通常受处理器性能限制。如果主数据库中并行发生更改,则在恢复期间,所有更改将按顺序执行-从日志中读取顺序。因此,恢复时间与恢复点距离备份终点的距离线性相关。因此,您必须经常进行完整备份-对于事务负载较低的数据库,至少每周一次,在每天复制高负载数据库之前,至少要进行一次完整备份。



增量备份



为了加快点对点恢复,我希望能够尽可能频繁地进行备份,但同时又不占用额外的磁盘空间,也不会使数据库承担备份任务。



解决方案是增量备份,即仅复制自上次备份以来已更改的数据页。

增量备份仅对使用可变数据结构的DBMS有意义。



可以从完整备份(累积副本)和任何以前的副本(差异副本)中计算增量。







不幸的是,没有统一的术语,并且不同的制造商使用不同的术语:



微分 累积的

甲骨文 微分 累积的
PostgresPro 增加的 --
Microsoft SQL服务器 -- 微分
IBM DB2 三角洲 增加的
MySQL企业版 增加的 微分
Percona服务器 增加的


使用增量备份,点对点还原过程如下所示:



  • 恢复还原之前进行的最后一次完整备份;
  • 增量副本将还原为完整副本;
  • 将日志从备份开始的位置滚动到恢复的位置。


具有累积副本可加快恢复过程。因此,例如,要将基本状态还原到T3和T4之间的某个点,必须还原两个增量副本,并且还原到T4之后的一个点-仅一个。

显然,一个累积副本的容量小于几个差异副本的容量,因为某些页面已更改了几次,并且每个增量副本都包含其自己的页面版本。



有三种创建增量副本的方法:



  1. 创建完整副本并计算与先前完整副本的差异;
  2. 分析日志,创建更改页面列表并备份列表中包含的页面;
  3. 请求更改数据库中的页面。


第一种方法可以节省磁盘空间,但是不能解决减少数据库负载的问题。此外,如果我们有完整备份,那么将其转换为增量备份是没有意义的,因为还原完整备份比还原先前的完整副本和增量要快。通过这种方法,最好将具有内置重复数据删除机制的节省磁盘空间的任务转移到特殊组件上。这些可以是特殊的存储系统(EMC DataDomain,HPE StorageWorks VLS,整个NetApp系列),也可以是软件产品(ZFS,Veritas NetBackup PureFile,Windows Server重复数据删除)。



第二种方法和第三种方法在确定更改页面列表的机制上有所不同。解析日志会占用更多资源,此外,您还需要了解日志文件的结构才能实现。最容易询问数据库本身哪些页面已更改,但是为此,DBMS内核必须具有跟踪更改的块的功能(块更改跟踪)。



增量备份功能最初是随Oracle Recovery Manager(RMAN)软件引入的,该软件随Oracle 8i发行版引入。 Oracle立即实施了已更改的块跟踪,因此无需解析日志。



PostgreSQL不跟踪更改的块,因此由俄罗斯公司Postgres Professional开发的pg_probackup实用程序通过分析日志来检测更改的页面。但是,该公司还提供PostgresPro,其中包括一个用于跟踪页面更改的ptrack扩展。当将pg_probackup与PostgresPro一起使用时,该实用程序会像RMAN一样向数据库本身查询已修改的页面。



像Oracle一样,Microsoft SQL Server跟踪已修改的页面,但是BACKUP命令仅允许完整和累积备份。



DB2能够跟踪更改的页面,但是缺省情况下它是禁用的。启用后,DB2将允许完整,差异和累积备份。



本节中描述的工具(pg_probackup除外)与基于文件的备份工具之间的重要区别在于,它们查询数据库中的页面图像,而不是从磁盘本身读取数据。这种方法的缺点是基座上的附加负载很小。但是,此缺陷可以用页面读取始终正确的事实来弥补,因此,在备份期间无需启用特殊的日志记录模式。



再次注意,增量备份的存在并不能代替将日志还原到任意时间点的要求。因此,在工业数据库中,日志不断地重写到外部介质,并且按计划创建完整和/或增量备份。



当今增量备份理念的最佳实现是零数据丢失恢复设备(Oracle术语中的工程系统)-专门的Oracle解决方案,用于备份其自己的数据库。该联合体是具有大量磁盘的服务器集群,在其上安装了Recovery Manager软件的修改版,并且可以与其他Oracle软件和硬件联合体(Database Appliance,Exadata,SPARC Supercluster)以及传统基础架构上的Oracle数据库一起使用。与“常规” RMAN不同,ZDLRA实施“永远增量”的概念。系统仅创建一次数据库的完整副本,然后仅创建增量副本。其他RMAN模块可让您合并副本,从增量副本创建新的完整副本。



值得俄罗斯开发者称赞的是,pg_probackup也能够合并增量副本。







与许多类似的问题不同,“哪种备份方法更好”问题具有明确的答案-最好的是所用DBMS的本机实用程序,它提供增量备份的功能。



对于DBA而言,选择备份策略以及将数据库备份集成到公司基础结构中的问题更为重要。但是这些问题不在本文讨论范围之内。



All Articles