对于一个数据库完整备份来说,备份的速度很大程度上取决于下面两个因素:读磁盘数据、日志文件的吞吐量,写磁盘数据文件的吞吐量。
下图是备份过程中磁盘的变化情况:
读吞吐量
读吞吐量的大小取决于磁盘读取数据的速度,而磁盘读取的速度又取决于数据文件在磁盘中的位置。因此,位于不同盘符上不同数据库文件的读取速度都不相同。
测量读吞吐量的一个方法就是进行一次数据库完整备份,然后使用Windows性能监控器(perfmon)来监控数据库文件所在磁盘的Read bytes/sec 性能计数器。保存备份文件的磁盘应该在物理上区别于数据库文件所在的磁盘,否则测量精度会不准确。当然备份同时也应该会有另外一些来自系统或是其他应用程序对磁盘的读取操作。
注意:如果你使用完整备份来监测磁盘读写吞吐量的话,那么这个测试用的备份文件应该和其他常规备份放在一起,以便恢复时使用。也就是说,如果你在测试备份文件之后又进行了常规差异备份,那么这些差异备份就会以这个测试备份为还原的起始点。
假设数据库所有文件的大小都是相等的,那么你获取的最小测量值就是你指定数据库在系统中最大的备份吞吐量了。
另一个测量读吞吐量的方法是在NUL设备上执行备份,如下:
BACKUP DATABASE AdventureWorks TO DISK = 'NUL' WITH COPY_ONLY
注意我们使用了COPY_ONLY选项,这个选项仅仅在SQL Server 2005及以上版本中才提供。你可以在SQL Server2000上执行相同的备份,只是要忽略这个选项,但是一定要小心。因为备份到NUL设备也会被认为是一个有效备份,这就意味着当你执行备份到NUL设备后,你后续的所有差异备份都将不可用,除非你在执行备份到NUL设备后,再执行一次常规的数据库完整备份。假如你执行事务日志备份到NUL设备,那么你将破坏日志恢复链,导致后续事务日志备份不可用。
如果你必须在SQL Server 2000上执行备份到NUL设备的话,一定要做好备灾恢复的准备。
假设我现在已经测量出我的AdventureWorks读吞吐量为46MB/sec。这就是说,46MB/sec是最大的备份吞吐量了,也是我的磁盘能提供给SQL Server备份读线程最快的速度了。那我们如何提高这个速度呢?使用更快的磁盘肯定是一种方法。另外的方法就是把数据库文件分散到多个物理磁盘上,以便于在读数据时可以同步创建多个读线程。减小数据库文件的碎片级别也可以提高吞吐量,特别是当数据库文件有大量碎片存在时。
写吞吐量
现在开始说说写吞吐量。执行一个文件备份,在我的系统中,我得到了如下的结果:
BACKUP DATABASE successfully processed 7529 pages in 3.300 seconds (18.688 MB/sec).
上面的结果表明写吞吐量在这里成为了瓶颈。我的磁盘可以提供46MB/sec的数据,但是写速度仅为18.688MB/sec。实际上,我把备份文件放在了同数据文件相同的磁盘上,当我把备份文件放在不同的物理磁盘上时,我得到如下的结果:
BACKUP DATABASE successfully processed 7529 pages in 1.421 seconds (43.399 MB/sec).
上面的结果已经好很多了。现在读写速度都取决于磁盘了,整体的吞吐量已经明显提高了。所以把备份文件放到不同的物理磁盘上就是一种提高写吞吐量的方法。另一个方法就是把备份分散成不同的文件。如果磁盘可以控制它的话,那么文件可以位于相同的物理磁盘上。如果不能,你最好把文件分散到不同的物理磁盘上。使用更快的磁盘存储备份文件是另一个好的选择。
然而,让我们回到第一步,再看看那个整体图。想一想备份吞吐量的第一步是读吞吐量。也就是说即使你的写吞吐量达到150MB/sec,但是如果读吞吐量只有46MB/sec的话,也无济于事,你能获得的最大备份吞吐量还是46MB/sec。
总结
首先我们总结一下我们都做了什么:
我们测量了读吞吐量为46MB/sec,我们讨论了如下方法来提高这个数值:
我们在数据库文件所在磁盘执行了备份执行,备份吞吐务为18MB/sec。很糟的速度,我们知道读吞吐量为46MB/sec,所以我们把目标放到了写吞吐量上。然后,我们把备份文件放到了与数据库文件不同的物理磁盘上。备份吞吐量为43MB/sec。速度不错。我也还可以提高这一数值吗?看起来好像是不行了。但是如果我们的写吞吐量仅仅为25MB/sec的话,我们还可以从以下几方面来考虑:
补充说明
为了获得最好的备份吞吐量,下面这几点在最开始创建数据库时就应该考虑到。实际上,下面这几点也同样适用于提高你数据库的应用性能。
获取备份速度数据
你可以从msdb..backupset表中获取备份速度数据。backup_start_date,backup_finish_date和backup_size列提供了计算备份速度所需的所有数据细节信息。注意备份大小不是定义数据库大小所必需的,因为SQL Server 2005不备份包括已被删除数据的数据页。具体细节请参见article。
下面的脚本可以显示出你所有数据库的备份时间:
SELECT database_name, backup_start_date, CAST(CAST((backup_size / (DATEDIFF(ss, backup_start_date, backup_finish_date))) / (1024 * 1024) AS NUMERIC(8, 3)) AS VARCHAR(16)) + ' MB/sec' speed
FROM msdb..backupset
ORDER BY database_name, backup_start_date
本文翻译自sqlbackuprestore,更多精彩内容请浏览http://www.sqlbackuprestore.com