SQL SERVER运维日记--收缩数据库
一个小故事
某天,小王正在和HR妹妹闲聊,正HAPPY时,,突然收到系统告警消息,数据库磁盘被剩余空间500M,OMG,不行,磁盘快满了,要是业务要停了,,那就小王只能删库到跑路了,,,
先检查下,有没有可以删除的不用的文件,结果都是重要的或者拿不准的。先收缩下数据库吧,点击运行。等收缩完成就可以继续去根HR妹妹聊天了。突然电话座机和手机齐鸣,小王心里一种不祥的预感呢?好像这个场景在哪里见过。。不会是数据库阻塞了吧?? 手忙脚乱的先接起手机,因为来电显示是某业务部门主管 “小王啊,,现在系统卡死了,全部不动了,是怎么回事啊,你赶紧处理下”,,“恩,好的,我马上检查下”,然后又接起座机,是另外一个部门的主管说报表看不了。慌忙应付完了,赶紧检查数据库执行中的语句。 果然数据库产生大量的阻塞,,连带数据库服务器的操作都变得好慢(是我的心理作用吗?)。正准备先把收缩操作取消了,,电话有同时响起了,,,唉,不管了,先处理问题。然后点击取消。经过漫长的等待,,终于完成了,然后打电话跟各个部门解释,,写事故报告,,悲剧,,今天的午饭都不想吃了。
这个场景是不是很熟悉啊,关于数据库收缩的问题,是我在群里,论坛里,看到新人问过最频繁的问题之一。今天这篇文章对数据库收缩进行有个框架性说明,希望小伙伴在以后遇到相关的
问题时,做到心中有数。
关于收缩的建议
不到万不得已,千万不要收缩数据库。收缩数据库影响极大:
1.收缩数据库对数据库的影响极大,产生大量日志和碎片,而且会锁表。如果你的库当前正在被使用,收缩不下去非常正常。
2.收缩数据库一定要手工来做的,而且是在维护窗口期做的事。
3.尽量使用语句来执行,可以提示错误
下面的文章详细介绍:
http://www.sqlskills.com/blogs/paul/why-you-should-not-shrink-your-data-files/.
收缩的正确姿势
在不得不收缩的时候,参考下面的步骤
1.找到数据库中最大的几个表,重建所有索引。首先尝试指定Truncate Only收缩方式.它只是移除文件尾部的空闲空间,并不重新组织已经使用的数据页。
DBCC SHRINKDATABASE (AdventureWorks2012, TRUNCATEONLY);
2 最后才考虑,不带选项的收缩。收缩不要一次性全部收缩。 可以每次收缩2G左右。不要把空间可用空间全部收缩了,可以剩余一部分比如4G。收缩完后,记得重建索引.
补充:
还有一种办法就是新建文件组,使用CREATE INDEX ... WITH(DROP_EXISTING = ON)ON语法将所有相关的的表和索引移动到新文件组。然后收缩旧的文件组。
3.可在进程中的任一点停止 DBCC SHRINKDATABASE 操作,任何已完成的工作都将保留。
4. 不能在备份数据库时收缩数据库
可能需要收缩的场景
1.你删除了大量数据,而且数据不太可能增长。
2.要移除某个文件时,你需要先清空数据文件。
总结
那我们处理磁盘空间不足的最好的办法是什么呢?最好的办法是在最初规划时,预估好未来一年或者二年的数据增长。给磁盘划分足够的空间。设置好数据库的初始大小,并且将自动增长使用固定量增长。