SHRINKFILE失败-为什么增加文件大小可以解决?


10

我正在运行一些SHRINKFILE操作来清理文件组中的一堆微小的不必要文件。对于其中一种收缩,以下命令将导致错误:

DBCC SHRINKFILE (N'myfile' , EMPTYFILE)'

无法缩小数据库ID x的文件ID x,因为它正在被另一个进程缩小或为空

它不是空的也不是收缩的。它正在除我以外的任何人当前未使用的数据库上运行。自动收缩功能未启用,也从未启用过。但是,如果真的很重要,在我开始使用该数据库之前,会定期对其进行手动收缩。

SQLServerCentral上,十年前的一个线程建议在文件中添加一些MB,因为“重新设置内部计数器或开关会告诉它现在不在收缩中”。

这很有效-很棒。但是,谁能更详细地说明SQL Server内部的工作原理/原因?


1
无法告诉您答案,但是赞成,因为这是一个方便的技巧,可以知道我将来是否会遇到这种情况!
John Eisbrener

如果可以复制,也许在收缩期间设置的文件标题页上有一些标志?
马丁·史密斯,

是的,我可以在测试实例上试一试,但这是产品,因此绝对没有尝试在此处复制它的奢侈。
LowlyDBA

Answers:


5

正如Martin Smith在评论中所建议的那样,我在文件头页面中四处寻找。我认为这是答案的一部分,但这主要是基于观察在执行收缩和其他操作之间文件头页面标志值的更改而进行的推测。


首先,我创建了一个数据库进行测试,其中包括一个辅助文件组:

CREATE DATABASE [Shrinkfile_Test]
ON PRIMARY
(
    NAME = N'Shrinkfile_Test',
    FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.SQL2016\MSSQL\DATA\Shrinkfile_Test.mdf',
    SIZE = 8192KB,
    FILEGROWTH = 65536KB
),
FILEGROUP [SECONDARY]
(
    NAME = N'ShrinkFile_Test_Secondary',
    FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.SQL2016\MSSQL\DATA\ShrinkFile_Test_Secondary.ndf',
    SIZE = 1024KB,
    FILEGROWTH = 65536KB
)
LOG ON
(
    NAME = N'Shrinkfile_Test_log',
    FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.SQL2016\MSSQL\DATA\Shrinkfile_Test_log.ldf',
    SIZE = 73728KB,
    FILEGROWTH = 65536KB 
)
GO

USE Shrinkfile_Test;
GO

我查看了“第0页”中的辅助文件,即file_id 3:

DBCC TRACEON (3604);
GO
DBCC PAGE (N'Shrinkfile_Test', 3, 0, 3);

有一个叫做场m_flagBits具有的价值0x208

如果我清空此文件:

DBCC SHRINKFILE (N'ShrinkFile_Test_Secondary' , EMPTYFILE);

m_flagbits字段保持不变(0x208)。没那么有趣,但是现在我遇到了您所报告的情况:如果我再次尝试清空文件,则会收到此错误:

数据库ID 19的文件ID 3无法收缩,因为它正在被另一个进程收缩或为空。

我将尝试扩展文件(对您有用的解决方案):

ALTER DATABASE ShrinkFile_Test
MODIFY FILE
(
    NAME = ShrinkFile_Test_Secondary,
    SIZE = 1025KB
);
GO

现在m_flagbits0x8

此时,再次清空文件成功将返回0x208您期望的值。

我发现有趣的是,如果我在重新增长文件后执行此操作(AKA标志位值为0x8):

USE [master]
GO
ALTER DATABASE [Shrinkfile_Test] MODIFY FILEGROUP [SECONDARY] READONLY
GO

该文件is_read_onlysys.databases表中标记为,并m_flagbits设置回0x208因此,在缩小文件并将其设置为只读时,似乎设置了一些类似的文件级标志。

我最好的猜测是,此值与其他(内部)标志一起使用以指示文件可以收缩。增大文件似乎会取消设置该标记(至少在中可见m_flagbits)。

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.