删除辅助数据文件。DBCC SHRINKFILE:无法移动页面,因为它是工作表页面


10

我为创建了太多辅助数据文件(.ndf)tempdb。要删除多余的文件,我需要清空文件(内容将移至其他文件):

DBCC SHRINKFILE('tempdbfile8', EMPTYFILE);

然后删除文件:

ALTER DATABASE tempdb REMOVE FILE tempdbfile8;

但是EMPTYFILE命令返回错误:

DBCC SHRINKFILE: Page 8:41920 could not be moved because it is a work table page.
Msg 2555, Level 16, State 1, Line 2
Cannot move all contents of file "tempdbfile8" to other places to complete the emptyfile operation.

不用担心,我只需要找到正在使用此页面的对象即可对此进行操作:

DBCC TRACEON (3604)
DBCC PAGE(2,8,41920) --dbid=2, fileid=8, pageid=41920

该命令返回很多信息,其中包括object_id。但:

Metadata: ObjectId = 0 

我不知道该怎么办。是什么猫阻止了此页面的移动?如何找到该对象,过程,会话或其任何内容?任何帮助将不胜感激,但请注意,将所有内容保留不变或删除其他文件不是解决此问题的有效方法;)。

编辑:

我要删除文件,因为我们过去一直遵循“最佳实践”,即为每个处理器核心创建一个文件(相同的初始大小,相同的增长率)。但是据我所知,除非遇到争用问题,否则没有必要在同一设备上创建其他tempdb文件。在我们看来,这是有道理的,因为我们已打开MPIO,并且存储设备可以处理4条路径。但是有一个错误,我们最终使用6核cpu总共生成了5个文件。它比MPIO路径多,比CPU内核少,而且不是偶数。它可能不会引起任何问题,但似乎并不正确:)。

通过将其中一个数据库(我怀疑是造成问题的数据库)设置为单用户模式(立即回滚),我终于能够清空并删除文件而无需重新启动服务器。它有效,但我很幸运。我真正想要的是始终能够跟踪页面:)。


DBCC PAGE命令不正确,应该类似于dbcc page(2,41920,1)。1,2,3取决于您想要的输出。
Shanky

如果上述方法不起作用,则可能必须在硬件中执行以下操作:删除文件,然后重新启动sql server,以便它只使用未删除的文件。您能否参考此链接daveturpin.com/2011/07/how-to-drop-a-tempdb-database-file
Shanky

2
@Shanky命令正确。可以将0..3作为第四个参数传递:dbcc page ( {'dbname' | dbid}, filenum, pagenum [, printopt={0|1|2|3} ])关于您的解决方案:它可以工作,但我真的很想在不降低实例性能的情况下执行此操作。
亚当·鲁尼斯基

好的..我告诉您更简单的dbcc页面形式。请注意是未记录的命令。您是否检查了我发布的链接
-Shanky

1
我认为不重新启动实例来解决此问题是不可行的。显然,您已经尝试跟踪该工作表是什么(这将有助于确定谁拥有它),但是失败了。顺其自然,或随额外的文件一起生活,直到可以重新启动为止。
亚伦·伯特兰

Answers:


5

重新启动服务器就足够了-应该清除这些工作表。但是我可能会以单用户模式(-m)启动它,以防止其他进程在成功删除这些文件之前创建工作表。然后重新定义所需的文件tempdb;也许删除不必要的文件,更改大小等。您还应该确保文件个数均匀,它们都设置为相同大小,并且它们都具有相同的自动增长设置(以MB为单位,而不是%)。同时也是考虑TF 1117和TF 1118(起点)的好时机。

对于要在再次启动SQL Server之前从文件系统中删除文件的建议,我会非常警惕-它可能根本不会启动。

(不过,我也想知道实际的问题是什么。文件太多并不会对您造成伤害。)


@@ Aaron当然,您需要谨慎删除它,它必须为空,但这在msdn.microsoft.com/en-gb/library/ms175574.aspx中有记录。已经尝试过,并且SQl Server tempdb联机。
Shanky

5
@Shanky我曾经尝试以每小时138英里的速度行驶,但是我没有被拉过。这是否意味着我应该继续这样做,明天就没有机会被拉扯?在建议风险更高的方法之前,先尝试正确的方法要安全得多。恕我直言。尤其是因为他现在无法清空文件-您是否认为除了错误消息所抱怨的工作表之外,文件中还有其他内容吗?该错误不会产生所有对象的详尽列表,而只会输出第一个对象。
亚伦·伯特兰

确实有一些正在使用tempdb的东西,因此不允许它清空文件,这很难猜到。可能他使用的排序运算符是一些仍需要tempdb的查询。DMV可以帮助找到sys.dm_db_task_space_usage sys.dm_db_session_space_usage sys.dm_db_file_space_usage
Shanky

重新启动是这里的选项,但是即使他没有清空文件并尝试删除tempdb文件,也会说tempdb文件无法删除,但同时系统目录已更新,并且重启后该文件将消失。我想这是tempdb的默认行为,所以我建议并且仍然认为即使使用数据文件也可以删除数据文件。我在第二条评论中发布的链接中也有同样的内容。
Shanky

1
@Shanky,那些DMV可以为与该文件无关的各种事情返回数千行-那么您打算如何缩小它的范围?而且由于您的方法也必须重新启动,为什么不先尝试简单的方法呢?对不起,我只是不同意“硬方法”应该是第一个建议。
亚伦·伯特兰

2

https://social.msdn.microsoft.com/Forums/zh-CN/2a00c314-f35e-4900-babb-f42dcde1944b/dbcc-shrinkfile-page-411283400-could-not-be-moved-because-it-is-工作表页面?论坛= sqldatabaseengine

正如Mike在msdn论坛中所建议的那样,工作表通常与计划缓存相关联。清除它们也会删除工作表,然后可以缩小Tempdb。这对我有用。这样也可以节省服务器重新启动的时间。由于SQL Server必须再次重新创建执行计划,因此会产生一些开销。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.