MS SQL Server数据库备份恢复

1. 备份策略
RPO(Recovery Point Objective, 恢复点目标)
- 可以接受多少数据遗失
RTO(Recovery Time Objective, 恢复时间目标)
- 还原可以花费多久时间,直接影响业务需要停多久时间。
备份策略对应的需求
- 备份的类型与频率:全量,增量,差异,日志,多久备份一次。
- 使用的备份介质:磁带、机械磁盘、ssd
- 备份与介质的保存期限,过期失效
- 备份测试原则,保证备份的数据完整,正常的测试方法就是再恢复一下,看备份的数据是否都存在。
2. 恢复模式
2.1 事务日志
首先了解下事务日志,任何数据库在写的时候都包括两个部分,一部分是数据,一部分是日志。微软的MS SQL Server称为事务日志,mysql的日志称为binlog。

当增、删、改数据时,会修改buffer cache(此修改是在内存里),然后将修改操作记录到磁盘上的日志文件里面,当到达checkpoint点时,再将buffer cache中的数据写入到数据文件中,当把数据写完之后,buffer cache中的脏数据(提交过的内容)会被清空。所以物理备份一般都会包括两部分数据:日志和数据。
2. 事物日志作用
2.1 在需要时,回滚交易
2.2 出现故障时,还原数据库
装好数据库之后,最好将数据和日志设置在不同的磁盘lun上,这样当其中一个磁盘坏了时,使用另一个磁盘也可以恢复数据。
2.3 事务日志依时间顺序循环写入
当数据文件满了,会清空数据文件,从头写入;那如果想让日志一直写下去,那日志文件就会无限增大,那这里就涉及到日志的截断原则。

2.4 日志的截断原则基于恢复模式
恢复模式和数据库恢复没有关系,恢复模式指的是日志的记录方式或者记录机制。
2.4.1 简单模式
自动截断日志以保持小的空间需求。
日志分活动日志和不活动日志。活动日志就是操作数据还没有写入到数据库里;不活动日志就是操作的数据已经写入到数据库里了,日志可以截断了,截断就是说,我这条日志(假设是一条不活动日志)以及之前的日志对应的数据都已经写入到数据库里,可以截断了,后面的日志可以接着我往后写,写到文件尾巴,然后再循环到日志文件头写入,因为日志文件前面的不活动日志截断了,对应的日志会自动清空,这就是循环写入。

不允许做日志备份。
由于非活动日志的自动截断清空,导致做不了日志备份。
简单模式下,数据库绝大多数的高可用做不了,因为微软的数据库高可用依赖日志备份。
简单模式下,如果数据坏掉了,也做不了数据库还原,因为日志被删掉了。
生产环境下不建议使用简单模式;用作测试的时候或者数据不重要的时候可以考虑使用简单模式。
2.4.2 完整模式
日志备份管理
完整模式是最常用的一种模式,但是需要我们自己管理日志,不像简单模式那样做自动截断清空的操作,完整模式会一直无限的往日志文件里增加。那日志文件越来越大怎么办?有且只有一种方法,那就是后面3.4小节说的事务日志备份。
避免因为数据文件损坏或遗失导致数据遗失
因为日志文件一直在的,所以数据文件坏了,我们也可以结合日志进行恢复。
2.4.3 大容量日志模式
日志备份管理
可以增强大容量复制操作的效率
为许多大容量操作使用最少记录以减少日志的空间使用量
大容量日志模式使用场景不多,大容量日志模式是针对批量导入数据的,比如一次性导入上千万条数据,数据库系统会先记录日志,再导入数据,使用大容量日志模式,只记录导入的头和尾,中间导入的数据就不记录了,这样就可以减少记录以减少日志的空间使用量。导入失败了,因为数据文件一直是存在的,大不了重新导入一次。
使用大容量日志模式,可以加快大容量数据导入速度。
上面的恢复模式决定着备份机制。
3. 数据库备份
Microsoft SQL Server备份类型
3.1 完整数据库备份策略
所有数据文件与事务日志中的部分日志。
完整备份是其他备份模式的基础。
首先思考一个问题:假设完整备份从9:00开始,12:30结束,那9:00 - 12:30之间数据库里产生的日志会不会备份走?

答案是:会备份走。
那就会又有疑问了,如果是结束时间点,那什么时候结束呢?数据一直写,备份就结束不了了吗?这里微软借助了日志功能,备份开始的时候,会在日志上打一个标志,备份结束的时候再在日志上打一个标志。备份期间产生的数据,先记的日志,结束的时候再把这部分数据写到备份里面。日志标志之间的数据会备份,之后再产生的日志就不会备份了。
完整备份包含所有数据文件,同时也会备份部分日志,也就是备份开始点和结束点之间生成的日志以及对应的数据。
在简单模式中,数据库只能还原到上次备份执行的时候。
在数据不常被修改的生产环境中,可当作最佳解决方案或在测试环境中使用。
创建好数据库之后,必须做一次完整备份,这样数据库才会切换为完整模式,之后如果数据库数据文件换了,就可以基于日志进行恢复,否则数据库是以简单模式运行。
当全备很慢的时候,原因很大概率是出在你网络速度和磁盘介质读写速度上,,底层备份是以多线程的形式,多个页同时往介质上写。
推荐业务低峰期去做备份。
3.2 差异备份策略
从上次完整数据库备份后数据库变更过的部分。
包含执行完整与差异数据库备份。
差异备份只包括变更过的数据。
用于数据库的某部分较其他剩余部分更频繁地被修改时的场景。

时间长了,可以想到差异备份的数据量也会很大。
3.3 部分与文件群组备份策略
主要文件组,每个读/写文件组以及任何指定的只读文件组。
原理图:

特点:
适用于大型数据规模的数据库,可以更快地备份与还原。
管理更复杂。
可以加快恢复速度,比如上图中为了业务快速恢复,可以先恢复G8,其他组可以延迟恢复。
建议把文件组看做一个存储边界,不建议对单个文件做备份,单个文件里的数据是不全的,无法恢复,最好是文件组级别。如果文件组里本身就是一个文件的话,那个备份单个文件是一样的。
只要不是恢复主要文件组,在企业版上,恢复过程中,可以保持数据库联机。只有恢复的那一部分才需要脱机。
3.4 事务日志备份策略
任何已记录在记录文件的数据库变更。
事务日志备份也叫增量备份,依赖于完整备份,不能独立存在。
至少包含完整与事务日志备份。
事务日志可以恢复到特定时间点。
在发生数据文件遗失时,允许数据库能够完整还原。
事务日志备份的潜在风险:
事务日志可以多频次的备份,备份链太长的话,如果其中某一次的事务日志备份丢失了,那丢失点后的数据就恢复不回来了。

一般会结合差异备份制定备份策略方案,比如差异备份数据量超过30G,后面的我就改成增量备份,这样也可以减少备份链节点数量。
3.5 尾部日志
就在还原操作之前对日志文件结尾执行记录备份。
“尾部日志备份”捕获尚未备份的任何日志记录,以防丢失所做的工作并确保日志链完好无损。
每次执行尾部日志备份时,必须使用完整恢复模式或是大容量日志恢复模式。
其他备份只会备份一部分数据,备份结束点之后的数据就不会备份了。当数据库坏掉之后,不会再有新的正常备份了,剩余未备份的日志就是尾部日志,尾部日志备份就是为了备份这部分数据。因此一般都是在灾难发生时,要执行尾部日志备份。下面是我的理解:

3.6 只复制
数据库或日志文件(不影响备份顺序)
3.7 其他考虑
系统数据库是一定要备份的,微软的系统数据库包括:master(账号、配置数据)、msdb(备份序列,各个job)、tempdb(不需要备份)、template(模板,也可以不用备)
为了可以恢复损坏页,建议启动checksum。
备份时可以指定64个备份设备,一份数据被拆分成64份,可以极大提高备份速度,设备间构建的是带区集。
使用mirror选项可以生成多个备份(最多4个)。
通过压缩备份选项可以提高备份设备的速度,压缩一般可以达到4-10倍之多,相对应的恢复速度也会加快。
4. 数据库恢复
SQL Server数据库的还原流程,是由3个阶段组成的:
Data copy
新建文件以及复制数据到文件中。
Redo
还原应用被提交的交易。
Undo
还原在还原时间点未被提交的交易,撤销未提交的操作。
当发生故障时,比如9点时误删除了几条数据,一般的恢复操作是通过全备和事务日志恢复到一个新的数据库里,然后把对应的数据select出来,插入到原先的数据库里。
例子:
备份计划:
在星期六晚间22:00,执行完整数据库备份
在星期一、星期二、星期四、星期五晚间22:00执行差异备份
从9:00-18:00,每个小时执行一次事务日志备份(每个小时整)
星期四的上午10点发生了故障,应该采取什么样的还原程序作业?
答案:
先做尾部日志备份
恢复全量备份
恢复周二的差异备份
恢复周三全天的日志备份
恢复周四9:00-10:00之间的事务日志
恢复尾部日志备份
5. 专业术语
5.1 LUN,Logical Unit Number, 逻辑单元号
其主要作用是为了给相连的服务器分配逻辑单元号。服务器识别到的最小的存储资源,就是LUN级别的。实际环境里,LUN可以是磁盘空间、磁带机或者media changer。
6. 参考资料
6.2