一、 什么是快照
数据库快照是 SQL Server 数据库(源数据库)的只读静态视图。换句话说,快照可以理解为一个只读的数据库。
快照通常用于以下场景:
- 提供指定时间的静态报表查询服务
- 用于恢复数据库,相比普通备份速度大大提高
- 与数据库镜像结合使用,提供读写分离
- 作为测试环境或大量数据变更前的备份
二、 快照的原理
数据库快照在页级运行。在第一次修改源数据库页之前,先将原始页从源数据库复制到快照。快照将存储原始页,保留它们在创建快照时的数据记录,对要进行第一次修改的每一页重复此过程。这个过程称为微软的写时复制技术(copy-on-write)。对于用户而言,数据库快照似乎始终保持不变,因为对数据库快照的读操作始终访问原始数据页,而与页驻留的位置无关。
与备份数据库复制整个数据库不同,快照并不复制整个数据库的页,而只复制在快照建立时间点之后改变的页。因此,利用快照进行数据库恢复时,也仅仅将那些做出改变的页恢复到源库,这无疑能大大提高恢复速度。
当查询快照数据库时,快照时间点之后更改的数据会查询稀疏文件。
三、 稀疏文件
为了存储复制的原始页,快照使用一个或多个稀疏文件。稀疏文件是NTFS文件系统的一项特性。所谓的稀疏文件,是指文件中出现大量0的数据,这些数据用处并不大,却一样占用着磁盘空间。NTFS对此进行了优化,利用算法将这个文件进行压缩。
稀疏文件刚创建时一般很小,甚至是空文件。比如下图就是一个稀疏文件,虽然逻辑上占了21M,但文件实际只占了128KB磁盘空间。
随着源库中更新的页越来越多,稀疏文件大小也不断增长。下图说明了两种相对的更新模式对快照大小的影响。
左边是在快照使用期限内仅有 30% 的原始页更新的环境;右边是在快照使用期限内有 80% 的原始页更新的环境。
所以,通常来说,当稀疏文件增长到源数据库文件大小的30%时,就应该考虑重建快照了。
除了通过快照数据库文件的属性来看快照的大小之外,也可以通过DMV来查看
select database_id,size_on_disk_bytes
from sys.dm_io_virtual_file_stats(db_id('snap_dbname'),1);
四、 使用快照的限制
使用快照存在诸多限制,由于列表太长(详细请参考http://msdn.microsoft.com/zh-cn/library/ms175158.aspx#LimitationsRequirements),这里只概括的说一下主要限制:
- 当使用快照恢复数据库时,首先要删除其他快照
- 在快照创建的时间点上没有commit的数据不会被记入快照
- 快照是快照整个数据库,而不是数据库的某一部分
- 快照是只读的,不能在快照上进行任何更改
- 在利用快照恢复数据库时,快照和源数据库都不可用
- 快照和源数据必须在同一个实例上
- 快照数据库的文件必须在NTFS格式的盘上
- 当磁盘不能满足快照的增长时,快照数据库会被置为suspect状态
- 快照上不能存在全文索引
其实,虽然限制看上去很多,但只要明白快照的原理,自然能推测出快照应该有的限制。
五、 快照的创建和使用
无论是使用SSMS或是命令行,快照只能通过T-SQL语句创建。
1. 查询源库数据文件分布情况
在创建数据库之前,首先要知道数据库分布在几个文件上,因为快照需要对每一个文件进行copy-on-writing。
2. 创建快照数据库
3. 使用快照数据库
创建成功后,就可以像使用普通数据库一样使用快照数据库了。
通过如下语句可以看到,快照数据库文件和源库文件貌似并无区别,仅仅是快照数据库文件是稀疏文件。
4. 删除快照数据库
删除快照数据库和删除普通数据库语法相同。
5. 利用快照恢复数据库
我们也可以利用快照恢复数据库,速度会比普通的备份恢复快得多。
六、 其他需要考虑的因素
- 快照数据库的安全设置继承源数据库的安全设置,能访问源数据库的用户或角色也能访问快照数据库。当然,因为快照数据库是只读的,所以无论任何用户角色都无法修改快照数据库。
- 随着快照存在的时间越来越长,快照会不断增长。所以推荐在快照达到源数据库大小30%之前,重新创建快照。
- 由于快照会拖累数据库性能,所以数据库不宜存在过多快照。