Removendo arquivos de dados secundários. DBCC SHRINKFILE: A página não pôde ser movida porque é uma página da tabela de trabalho

10

Eu tenho muitos arquivos de dados secundários (.ndf) criados para tempdb. Para remover os arquivos em excesso, preciso esvaziá-lo (o conteúdo será movido para outros arquivos):

DBCC SHRINKFILE('tempdbfile8', EMPTYFILE);

e exclua o arquivo:

ALTER DATABASE tempdb REMOVE FILE tempdbfile8;

Mas o EMPTYFILEcomando retorna o erro:

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.

Não se preocupe, só preciso localizar o objeto que está usando esta página para fazer algo a respeito:

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

O comando retorna muitas informações, object_id entre elas. Mas:

Metadata: ObjectId = 0 

Não tenho ideia do que fazer sobre isso. Que gato está impedindo que esta página seja movida? Como localizar esse objeto, processo, sessão ou o que for? Qualquer ajuda será apreciada, mas observe que deixar tudo como está ou remover outro arquivo não é uma solução válida para esse problema;).

EDITAR:

Estou removendo os arquivos, porque seguíamos as "práticas recomendadas" de criar um arquivo por núcleo do processador (mesmo tamanho inicial, mesma taxa de crescimento). Mas até onde eu sei, até que você tenha problemas de contenção, não há sentido em criar arquivos tempdb adicionais no mesmo dispositivo. No nosso caso, faz sentido, porque temos o MPIO ativado e o dispositivo de armazenamento pode lidar com quatro caminhos. Mas houve um erro e acabamos com um total de 5 arquivos com uma CPU de 6 núcleos. É mais que caminhos MPIO, menos que núcleos de CPU e não é um número par. Pode não causar problemas, mas simplesmente não parece certo :).

Finalmente, consegui esvaziar e remover o arquivo sem reiniciar o servidor, definindo um dos bancos de dados (que suspeitava causar o problema) para o modo de usuário único (reversão imediata). Funcionou, mas tive sorte. O que eu realmente quero é ser sempre capaz de rastrear a página :).

Adam Luniewski
fonte
O comando DBCC PAGE não está correto, deve ser como a página dbcc (2,41920,1). 1,2,3 depende do que você deseja na saída.
Shanky
Se o procedimento acima não funcionar, você poderá fazê-lo no hardware removendo arquivos e reiniciando o sql server para que apenas use arquivos que não foram excluídos. Você pode consultar este link daveturpin.com/2011/07/how-to-drop-a-tempdb-database-file
shanky
2
@ Shanky O comando está correto. 0..3 pode ser passado como quarto parâmetro: dbcc page ( {'dbname' | dbid}, filenum, pagenum [, printopt={0|1|2|3} ])Sobre sua solução: funcionaria, mas eu realmente gostaria de fazer isso sem interromper a instância.
Adam Luniewski
Ok ... eu estava lhe dizendo uma forma mais simples de página dbcc. Observe que o comando não está documentado. Será que você marcou ligação eu postei
shanky
11
Não acho viável resolver esse problema sem reiniciar a instância. Obviamente, você tentou rastrear o que é esta mesa de trabalho (o que ajudaria a determinar quem é o dono) e isso falhou. Aceite o impacto ou viva com os arquivos extras até poder reiniciar.
Aaron Bertrand

Respostas:

5

Reiniciar o servidor deve ser suficiente - essas tabelas de trabalho devem ser limpas. Mas eu provavelmente o inicializaria no modo de usuário único (-m) para impedir que outros processos criem tabelas de trabalho antes de remover esses arquivos com êxito. Redefina os arquivos necessários para tempdb; talvez excluindo arquivos desnecessários, alterando tamanhos, etc. Você também deve garantir que tenha um número par de arquivos, que todos estejam configurados para o mesmo tamanho e que tenham as mesmas configurações de crescimento automático (em MB, não em%). E pode ser um bom momento para considerar também o TF 1117 e o TF 1118 ( ponto de partida ).

Eu ficaria muito cauteloso com a sugestão de excluir os arquivos do sistema de arquivos antes de iniciar o SQL Server novamente - ele pode não ser iniciado.

(Eu também ficaria curioso sobre qual é o problema real. Ter muitos arquivos não machuca você realmente.)

Aaron Bertrand
fonte
@@ Aaron, é claro que você precisa ter cuidado ao removê-lo, deve estar vazio, mas isso está documentado aqui msdn.microsoft.com/en-gb/library/ms175574.aspx . Já tentei e o SQl Server tempdb fica online.
Shanky
5
@ Shanky Tentei dirigir 138 milhas por hora uma vez e não fui atropelado. Isso significa que eu deveria continuar fazendo isso, e que não há chance de ser puxado amanhã? Muito mais seguro para experimentar o apropriado caminho primeiro, antes de sugerir uma forma mais arriscada. NA MINHA HUMILDE OPINIÃO. Especialmente porque ele não pode esvaziar o arquivo agora - você acha que é possível que haja mais alguma coisa além da mesa de trabalho da qual a mensagem de erro está reclamando? O erro não produz uma lista exaustiva de todos os objetos, apenas gera o primeiro objeto.
Aaron Bertrand
Existe algo que realmente está usando o tempdb, portanto, não é permitido adivinhar o arquivo vazio. Que ele tenha usado o operador de classificação, é uma consulta que ainda precisa do tempdb. DMV pode ajudar que em encontrar sys.dm_db_task_space_usage sys.dm_db_session_space_usage sys.dm_db_file_space_usage
shanky
Reiniciar é a opção aqui, mas mesmo que ele não esvazie o arquivo e tente soltar o arquivo tempdb, ele diria que o arquivo tempdb não pode ser descartado, mas ao mesmo tempo o catálogo do sistema é atualizado e, após a reinicialização, o arquivo desapareceu. Acho que esse comportamento padrão com o tempdb foi sugerido e ainda acho que a remoção do arquivo de dados funcionaria mesmo que fosse utilizada. O mesmo está lá no link que eu postei no meu segundo comentário.
Shanky
11
@Shanky essas DMVs podem retornar milhares de linhas para todos os tipos de coisas que não têm nada a ver com o arquivo em questão - então, como você planeja reduzi-lo? Além disso, como você também precisa reiniciar o método, por que não tentar primeiro a maneira mais simples? Só não concordo com você de que "o caminho difícil" deve ser a primeira sugestão, desculpe.
Aaron Bertrand
2

https://social.msdn.microsoft.com/Forums/en-US/2a00c314-f35e-4900-babb-f42dcde1944b/dbcc-shrinkfile-page-411283400-could-not-be-moved-because-it-is- a-work-table-page? forum = sqldatabaseengine

Conforme proposto por Mike no fórum msdn, as tabelas de trabalho estão principalmente associadas ao cache do plano. Limpá-los também removeria a mesa de trabalho e você poderá encolher o Tempdb. Isso funcionou para mim. E isso poupa também a reinicialização do servidor. Haverá alguma sobrecarga, pois o SQL Server precisará recriar os planos de execução novamente.

sajeesh
fonte