Eu dei uma olhada na página do cabeçalho do arquivo, conforme sugerido por Martin Smith nos comentários. Acho que isso faz parte da resposta, mas é principalmente especulação baseada na observação de alterações nos valores de sinalização da página de cabeçalho do arquivo entre a realização de encolhimentos e outras operações.
Primeiro, criei um banco de dados para testar, incluindo um grupo de arquivos secundário:
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
O que eu olhei na "página 0" para o arquivo secundário, que é file_id 3:
DBCC TRACEON (3604);
GO
DBCC PAGE (N'Shrinkfile_Test', 3, 0, 3);
Há um campo chamado m_flagBits
que tem um valor de 0x208
.
Se eu esvaziar este arquivo:
DBCC SHRINKFILE (N'ShrinkFile_Test_Secondary' , EMPTYFILE);
Esse m_flagbits
campo permanece o mesmo ( 0x208
). Não é tão interessante, mas agora estou na situação que você relatou: se eu tentar esvaziar o arquivo novamente, recebo este erro:
O ID do arquivo 3 do ID do banco de dados 19 não pode ser reduzido, pois está sendo reduzido por outro processo ou está vazio.
Vou tentar aumentar o arquivo (a solução que funcionou para você):
ALTER DATABASE ShrinkFile_Test
MODIFY FILE
(
NAME = ShrinkFile_Test_Secondary,
SIZE = 1025KB
);
GO
Agora m_flagbits
é 0x8
!
Neste ponto, esvaziar o arquivo novamente com êxito retorna o valor 0x208
conforme o esperado.
O que eu acho interessante é que, se eu fizer isso depois de aumentar o arquivo novamente (o valor do AKA flagbits é 0x8
):
USE [master]
GO
ALTER DATABASE [Shrinkfile_Test] MODIFY FILEGROUP [SECONDARY] READONLY
GO
O arquivo está marcado como is_read_only
na sys.databases
tabela e m_flagbits
volta para 0x208
. Portanto, parece que há um sinalizador de nível de arquivo semelhante definido ao reduzir um arquivo e ao defini-lo como somente leitura.
Meu melhor palpite é que esse valor seja usado junto com algum outro sinalizador (interno) para indicar que um arquivo é elegível para ser reduzido. O aumento do arquivo parece desabilitar esse sinalizador (pelo menos o sinal visível m_flagbits
).