在使用sql server时您可能遇到过下面的情况,tempdb的数据文件初始大小为3mb, 随着对tempdb的使用,tempdb文件逐渐变得很大(例如30GB),导致了磁盘空间不足。 此时您需要立刻释放tempdb文件所占用的空间,这时你会有两个选择:

  1. 重启SQL Server。大家都知道SQL Server重启时会创建一个新的tempdb。由于tempdb的initial size并不会随着文件大小的增长而增长,重启SQL Server就会创建一个新的3MB的tempdb。
  2. 使用DBCC命令收缩tempdb的大小。如果当前tempdb实际被使用到的空间其实不大,只是文件尺寸很大的话,您可能会考虑使用dbcc shrinkfile来收缩tempdb。通常情况下,这种方案是可行。但是您需要警惕一个潜在的风险。下面是我最近遇到的一个实际的案例。

客户尝试使用dbcc shrinkfile依然无法收缩,但发现tempdb大小没有变化,仍然是30GB。客户搜索到了下面的这篇文章:

Shrink TempDB Transaction Log fails after overflow http://blogs.technet.com/technet_blog_images/b/sql_server_sizing_ha_and_performance_hints/archive/2011/03/03/shrink-tempdb-transaction-log-fails-after-overflow.aspx

http://www.sqlservercentral.com/blogs/james-sql-footprint/2012/04/06/clean-sql-server-cache/

于是尝试使用dbcc freesystemcache('ALL') , 然后使用dbcc shrinkfile,但发现tempdb仍然无法收缩。遇到这样情况可能是因为在使用dbcc freesystemcache('ALL')时,依然有session在引用tempdb,所以无法清除所有的internal objects,导致无法收缩。于是客户决定重启sql server。奇怪的是,SQL Server重启后,客户发现tempdb没有变回初始大小的3mb,而是依旧保持了30GB的尺寸。打开SSMS查看tempdb的初始大小,非常奇怪的,initial size变成了30GB…

为什么会出现这样的结果呢?原因是dbcc shrinkfile会把tempdb的initial size设置为语句运行完之后tempdb文件的当前大小。所以当shrinkfile没能成功收缩tempdb时,tempdb的initial size就变成了30GB,即使重启SQL Server, tempdb依旧还是占用了30GB的空间。

因此在执行dbcc shrinkfile前要千万小心咯。你需要确保没有session引用tempdb的情况下执行dbcc freesystemcache('ALL'), 之后再进行收缩。如果无法保证,那么就只能通过执行alter database,将initial size缩小,然后重启SQL Server来收缩tempdb了。Alter database语句如下:

alter database tempdb modify file(name='tempdev',size=10mb)

请注意,如果指定的size小于当前大小,文件是不会缩小的,但initial size会变成指定的size.

更多信息

===

  1. 需要注意的是,我们这里对tempdb的initial size的定义,是每次SQL Server重启后重新创建出来的新的tempdb的初始大小。而不是你在SSMS的数据库属性界面中看到的initial size的值。我们认为只有重启后tempdb的大小对用户才是有意义的。
  2. dbcc shrinkfile变更initial size的行为是在sql server 2008中引入的。 在sql server 2005里,dbcc shrinkfile并不会改变initial size,所以即使无法收缩,重启后tempdb也会变为之前的大小。
  3. 对于tempdb,当有新的数据插入并且现有可用空间无法容纳新的数据时,tempdb文件会按照Autogrowth属性进行增长,但是initial size并不会发生变化。那么initial size这个值到底存储在哪里呢?很遗憾,我在BOL中没有找到。 我尝试在打开SSMS展示initial size时捕获SQL Server trace, 但并没有找到实际表initial size的列和语句。但从实际效果来看,我找到了相应的替代品:

DMV sys.database_files的size表示当前大小。select size ,*From tempdb.sys.database_files

  1. SQL Server 2012的SSMS显示的tempdb的initial size和SQL Server重启后重新生成的tempdb的初始大小可能是不同的。而SQL Server 2005/2008/2008 R2的SSMS没有这个问题。根据第一点中我们对initial size的定义,建议如果要查看sql server 2012 tempdb的initial size,请使用DMVsys.master_files
  2. Alter database modify file语句改变tempdb的initial size的行为也是在sql server 2008(以及以后版本)中引入的。在2005中无法改变tempdb的initial size.
  3. Alter database modify file语句只可以改变tempdb的initial size,不会改变user database的initial size。当尝试更改user database时,如果指定的size小于当前size,会抛出下面的错误:MODIFY FILE failed. Specified size is less than current size.
  4. dbcc shrinkfile (Transact-SQL) http://technet.microsoft.com/en-us/library/ms189493(v=sql.90).aspx
  5. dbcc shrinkfile (Transact-SQL) http://technet.microsoft.com/en-us/library/ms189493(v=sql.100).aspx
  6. How to shrink the tempdb database in SQLServer http://support.microsoft.com/kb/307487

上述讨论所的知识点和技巧都是针对tempdb的,请不要将其应用于user database。关于user database的情况我会在后续的文章里介绍。

Tempdb initial size和dbcc shrinkfile的更多相关文章

  1. user database的initial size和dbcc shrinkfile

    之前我们讨论了dbcc shrinkfile改变tempdb initial size的情况.而用DBCC Shrinkfile去收缩一个user database,情况就比较简单了.让我们通过一些测 ...

  2. 收缩数据库 DBCC SHRINKFILE

    /* from: http://www.cnblogs.com/blackcore/archive/2010/12/27/1917911.html */ 数据库中的每个文件都可以通过删除未使用的页的方 ...

  3. SQL Server dbcc shrinkfile 不起作用

    方法 1.重建聚集索引. 方法 2.重建堆表. ---------------------------------------------------------------------------- ...

  4. DBCC SHRINKFILE收缩日志/收缩数据库/收缩文件

    DBCC SHRINKFILE 收缩相关数据库的指定数据文件或日志文件大小. 语法 DBCC SHRINKFILE    ( { file_name | file_id }        { [ ,t ...

  5. SQL Server 2008收缩日志文件--dbcc shrinkfile参数说明

    原文:SQL Server 2008收缩日志文件--dbcc shrinkfile参数说明 DBCC SHRINKFILE 收缩相关数据库的指定数据文件或日志文件大小. 语法 DBCC SHRINKF ...

  6. 笔记9-徐 DBCC SHRINKFILE不起作用的原因

    1 , , , , , , , , ,40) ,1 page_id pg_alloc ext_size obj_id index_id partition_number partition_id ia ...

  7. SQLSERVER将一个文件组的数据移动到另一个文件组

    SQLSERVER将一个文件组的数据移动到另一个文件组 有经验的大侠可以直接忽视这篇文章~ 这个问题有经验的人都知道怎麽做,因为我们公司的数据量不大没有这个需求,也不知道怎麽做实验 今天求助了QQ群里 ...

  8. 收缩TempDB的办法(转载)

    有时候在数据库上运行一个数据量很大的查询语句,会导致TempDB数据量剧增,具体查看下面链接文章: SqlServer 一个查询语句导致tempdb增大55G 找到TempDB剧增的问题后,接下来的问 ...

  9. SqlServer 一个查询语句以致tempdb增大55G (转载)

    SqlServer 一个查询语句导致tempdb增大55G 今天操作着服务器,突然右下角提示“C盘空间不足”! 吓一跳!~ 看看C盘,还有7M!!!这么大的C盘空间怎么会没了呢?搞不好等下服务器会动不 ...

随机推荐

  1. facebook 简单的图文分享

    参考网址:http://www.mrfangge.com/facebook-page-share-settings/ 首先在facebook 注册开发者,新增一个应用,这里就要一个生所的应用 app_ ...

  2. C 标准库系列之ctype.h

    ctype.h 主要提供了一些函数用以测试字符或字符处理的功能函数:包括字符判断检测.字符转换: 目前ASCII字符可分为以下一些类型,如:大写.小写.字母.数字.十六进制.空白字符.可打印字符.控制 ...

  3. [BI项目记]-BUG创建

    BUG是在项目过程中以及运维过程中经常遇到的工作项.在处理每一个BUG的过程中,通过项目管理系统把BUG相应的内容纪录下来也是很重要的.这里将介绍如何通过TFS来完成BUG的创建工作. 首先我们来看B ...

  4. asp.net core的TagHelper简单使用

    TagHelper(标签助手)是ASP.NET Core非常好的一种新特性.可以扩展视图,让其看起来像一个原生HTML标签. 应该使用TagHelper替换HtmlHelper,因其更简洁更易用,且支 ...

  5. 听大神说:https和http有何区别?(转)

    在做雅虎的时候,发现用第三方工具截取不到客户端与服务端的通讯,以前重来没碰到过这种情况,仔细看了看,它的url请求时基于https的,gg了下发现原来https协议和http有着很大的区别.总的来说, ...

  6. 外接Hdmi没有声音怎么设置

    参考 http://www.3lian.com/edu/2013/07-16/81152.html 在小喇叭图标上右键->播放设备->禁用HDMI

  7. python 面向对象初级篇

    Python 面向对象(初级篇) 概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发" ...

  8. HDU5937 Equation(DFS + 剪枝)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5937 Description Little Ruins is a studious boy, ...

  9. 关于用display:table让元素居中的小结

    我们都知道让元素垂直居中有一种简单的方法:给需要居中的元素用一个父级包起来,并给它设置样式:display:table:同时给这个父级设置好高度:再给需要居中的元素一个display:table-ce ...

  10. MongoDB数据库安装与连接