Удаление вторичных файлов данных. 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 пути. Но произошла ошибка, и мы получили всего 5 файлов с 6-ядерным процессором. Это больше, чем пути MPIO, меньше, чем ядра процессора, и это не четное число. Это может не вызывать никаких проблем, но просто не кажется правильным :).

Я наконец смог очистить и удалить файл без перезапуска сервера, установив одну из баз данных (которую я подозревал в возникновении проблемы) в однопользовательский режим (немедленный откат). Это сработало, но мне повезло. Что я действительно хочу, так это всегда быть в состоянии отследить страницу :).

Адам Луневски
источник
Команда DBCC PAGE неверна, она должна быть похожа на страницу dbcc (2,41920,1). 1,2,3 зависит от того, что вы хотите в выводе.
Шэнки
Если вышеприведенное не работает, вам, возможно, придется сделать это аппаратно, удалив файлы, а затем перезапустив сервер sql, чтобы он просто использовал файлы, которые не были удалены. Можете ли вы сослаться на эту ссылку daveturpin.com/2011/07/how-to-drop-a-tempdb-database-file
Shanky
2
@Shanky Команда верна. 0..3 можно передать как 4-й параметр: dbcc page ( {'dbname' | dbid}, filenum, pagenum [, printopt={0|1|2|3} ])О вашем решении: оно будет работать, но я бы очень хотел сделать это, не останавливая экземпляр.
Адам Луневски
Хорошо ... Я говорил вам более простую форму страницы dbcc. Обратите внимание, это недокументированная команда. Вы проверили ссылку, которую я опубликовал
Shanky
1
Я не думаю, что возможно решить эту проблему без перезапуска экземпляра. Очевидно, вы попытались отследить, что это за рабочий стол (что поможет определить, кому он принадлежит), и это не удалось. Возьмите удар или живите с дополнительными файлами, пока не сможете перезапустить.
Аарон Бертран

Ответы:

5

Перезапуска сервера должно быть достаточно - эти рабочие столы должны очиститься. Но я бы, вероятно, запустил его в однопользовательском режиме (-m), чтобы другие процессы не могли создавать рабочие таблицы до того, как вы успешно удалите эти файлы. Затем переопределите файлы, необходимые для tempdb; возможно удаление ненужных файлов, изменение размеров и т. д. Вы также должны убедиться, что у вас есть четное количество файлов, что все они имеют одинаковый размер и имеют одинаковые параметры автоматического роста (в МБ, а не в%). И это может быть хорошее время для рассмотрения TF 1117 и TF 1118 ( отправная точка ).

Я бы очень осторожно отнесся к предложению просто удалить файлы из файловой системы перед повторным запуском SQL Server - он может вообще не запуститься.

(Мне также было бы любопытно узнать, в чем проблема на самом деле. На самом деле, слишком много файлов не повредит вам.)

Аарон Бертран
источник
@@ Aaron ofcourse, вы должны быть осторожны, удаляя его, он должен быть пустым, но это задокументировано здесь msdn.microsoft.com/en-gb/library/ms175574.aspx . Попробовал и SQl Server tempdb выходит в онлайн.
Шэнки
5
@Shanky Я пытался проехать 138 миль в час один раз, и меня не остановили. Означает ли это, что я должен продолжать это делать, и что нет никаких шансов, что меня завтра остановят? Гораздо безопаснее сначала попробовать правильный путь, прежде чем предлагать более рискованный путь. ИМХО. Тем более, что он не может очистить файл сейчас - как вы думаете, возможно ли, что в нем есть что-то еще, кроме рабочего стола, на который жалуется сообщение об ошибке? Ошибка не приводит к исчерпывающему списку всех объектов, она выводит только первый объект.
Аарон Бертран
Есть что-то, что на самом деле использует tempdb, поэтому он не позволяет пустым файлам его сложно угадать. Может, он использовал оператор сортировки для какого-то запроса, который все еще нуждается в базе данных tempdb. DMV может помочь в поиске sys.dm_db_task_space_usage sys.dm_db_session_space_usage sys.dm_db_file_space_usage
Шэнки
Перезапуск здесь возможен, но даже если он не очистит файл и не попытается сбросить файл tempdb, он скажет, что файл tempdb не может быть удален, но в то же время системный каталог обновляется и после перезапуска файл исчезнет. Я полагаю, это поведение по умолчанию с tempdb, поэтому я предложил и все еще думаю, что удаление файла данных будет работать, даже если он используется. То же самое есть в ссылке, которую я разместил во втором комментарии.
Шэнки
1
@Shanky эти DMV могут вернуть тысячи строк для всех видов вещей, которые не имеют никакого отношения к рассматриваемому файлу - так как вы планируете сузить его? Кроме того, поскольку с вашим методом вы должны перезапустить, почему бы просто не попробовать сначала более простой способ? Я просто не согласен с тобой, что "трудный путь" должен быть первым предложением, извини.
Аарон Бертран
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- а-рабочий стол-страница? форум = sqldatabaseengine

Как предложил Майк на форуме msdn, рабочие таблицы в основном связаны с кэшем плана. Очистка их также приведет к удалению рабочего стола, а затем вы можете уменьшить Tempdb. Это сработало для меня. И это спасает вас от перезагрузки сервера. Это приведет к некоторым накладным расходам, поскольку SQL-серверу придется заново создавать планы выполнения.

sajeesh
источник