码迷,mamicode.com
首页 > 数据库 > 详细

关于shrinkdatabase的三个疑问

时间:2016-08-21 00:48:53      阅读:1402      评论:0      收藏:0      [点我收藏+]

标签:

shrinkdatabase

  shrinkdatabase用来压缩数据库,完整语法为dbcc shrinkdatabase( database_name|database_id|0  [ , percent]  [, notruncate|truncateonly] ) [with no_infomsgs]。在第一个参数中需要指定要压缩的数据库名或id,当设置为0则表示压缩当前数据库。第二个参数表示压缩后的数据库中剩余空间所占的百分比。第三个参数为可选参数,它有2个选项notruncate和truncateonly。最后参数表示取消严重级别从 0 到 10 的所有信息性消息。关于notruncate和truncateonly的介绍msdn的意思如下,notruncate和truncateonly都只针对数据文件,它们对日志文件无影响。notruncate会对数据库中的页进行移动,把数据文件末尾的页移动到前面的空闲空间。经过移动后数据文件尾部就会有一部分空闲空间,不过这部分空间并不会归还给文件系统,也就是说使用shrinkdatabase后你不会看到数据库的物理大小有任何改变。truncate不会对数据文件进行页移动,它会将数据文件尾部的空闲空间释放掉,也就是归还给操作系统,使用truncateonly后你会发现数据库的大小确实变小了。另外当使用notruncate时可指定percent参数,而对truncateonly来说指不指定percent都是一样,persent对truncateonly无效。另外笔者发现在SQL2012的官方文档中truncaeonly将只用于日志文件。

  当不指定notruncate和truncateonly时,那么将会首先执行notruncate操作,然后再执行truncateonly操作。使用shrinkdatabase后的结果如下所示。DbId表示要压缩的数据库id,可用sp_helpdb查看。FileId则是文件Id,可使用select * from sys.database_files查看。CurrentSize表示文件当前占用的8kb页数,MinimumSize表示文件最小的页数,也就是创建时的值,这里CurrentSize和MinimumSize相等表示文件已压缩到最小。UsedPage表示文件当前使用的页数,EstimatedPages表示数据库引擎估计能够收缩到的最小页数。压缩数据库时,无论怎样都不会小于显示为这个数据库指定的值,这个值可以是创建时指定的大小也可以是后续修改指定的大小。执行spaceused存储过程可以知道目前数据库所占的物理空间和未使用的大小。

技术分享

  在阅读msdn上的shrinkdatabase收缩原理时,里面讲述了很多关于使用shrinkdatabase收缩日志文件的内容,并且是统一说明persent并没有notruncate和truncateonly的区别,这让我开始怀疑上面关于notruncate和truncateonly的介绍,并产生了3个疑问:notruncate和truncateonly都只适用于数据文件,而msdn上有说shrinkdatabase 尝试立即将每个物理日志文件收缩到其目标大小?指不指定percent对truncateonly都没影响,可是msdn的意思是percent对truncateonly也会产生影响?notruncate和truncateonly对数据库到底进行了什么操作?于是我分不同的情况使用了shrinkdatabase来压缩数据库,每执行一次测试会删除数据库重新建立并插入数据。过程如下:

每次建立数据库并插入数据后的初始大小为

技术分享

第一段测试:dbcc shrinkdatabase(0,5,truncateonly)

 技术分享

exec sp_spaceused

技术分享

dbcc shrinkdatabase(0,10,truncateonly)

 技术分享

exec sp_spaceused

技术分享

dbcc shrinkdatabase(0,15,truncateonly)

 技术分享

exec sp_spaceused

技术分享

 

第二段测试:--为persent分别指定参数为5、10、15,发现结果都是一样的
dbcc shrinkdatabase(0,5,notruncate)
dbcc shrinkdatabase(0,truncateonly)
exec sp_spaceused

技术分享

技术分享

技术分享

 

第三段测试:dbcc shrinkdatabase(0,truncateonly)

技术分享

技术分享

 

第四段测试:dbcc shrinkdatabase(0)

技术分享

dbcc shrinkdatabase(0,5)

技术分享

dbcc shrinkdatabase(0,10)

技术分享

dbcc shrinkdatabase(0,15)

技术分享

 

   在上面操作过程中只有数据文件在变化,日志文件大小没有变化。但这并不能说明truncateonly和notruncate不用于日志文件,因为测试中日志文件并没有因日志写满而增加,而我们知道一个文件无论怎么收缩最后绝对是不会小于它创建时的大小。不过通过结果可以肯定的是truncateonly确实影响了数据文件。对于第二个疑问现在可以肯定msdn上写错了,truncateonly会受persent的影响而进行不同程度的收缩。可是从结果中又发现剩余空间占数据库总空间的百分比不是指定的persent参数,不过这三次truncateonly执行中可以发现database_size-unallocted_space-2(日志文件大小)=3.52M左右,这与预期一样数据库收缩时数据文件的真实数据大小是不会变的。接下来我又进行了三次实验,在实现truncateonly前先执行notruncate,却发现结果都一样,似乎是notruncate不受percent的影响,因为按msdn的理解是notruncate根据指定的persent移动数据页,最终数据页尾部剩余空间所占的百分比为percent,然后truncateonly负责删除数据文件尾部空间。于是我删除数据库重新插入数据后,直接执行不带参数的truncateonly,也就是上面第三段截图,结果证实notruncate不受percent的影响。没想到微软的官方文档上这个地方居然搞反了。

  到这里可以肯定第二个疑问中msdn的介绍是错误的,notruncate不受percent的影响,而truncateonly受percent的影响。但第一个疑问我手里没有日志文件因为空间不足而进行空间扩大的数据库,也不知道有什么方法可以快速增加日志文件大小,暂时无法肯定truncateonly会不会收缩日志。对于第三个疑问,现在只知道了truncateonly进行了什么操作,不清楚notruncate进行了什么操作。在前面测试过程中还有2次是测notruncate,不过截图我没有记录到本文,第一次执行dbcc shrinkdatabase(0,notruncate)发现可分配空间与执行前一样,第二次指定persent参数执行后可分配空间仍与执行前一样。关于这2个疑问如果阅读此文的前辈有什么想法欢迎留言。

关于shrinkdatabase的三个疑问

标签:

原文地址:http://www.cnblogs.com/fangyz/p/5781415.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!