10.10.25

Повреждение страницы заголовка файла

Автор: Paul Randal, Search Engine Q&A #21: File header pages, and file header corruption

Итак, что такое страница заголовка файла? В каждом файле данных самая первая страница 8КБ (то есть страница 0 в файле) отведена для хранения всех метаданных об этом файле. Как и для загрузочной страницы, вы можете посмотреть её содержимое с помощью DBCC PAGE — команда интерпретирует все поля, — либо воспользоваться командой DBCC FILEHEADER, которая делает это ещё удобнее. Эта команда недокументирована и не поддерживается (точно так же, как DBCC DBINFO для просмотра загрузочной страницы базы), но о ней уже писали и говорили в интернете, так что её существование не секрет.

Команда принимает имя базы данных или её ID плюс ID файла, заголовок которого нужно вывести. Здесь я создал базу данных FileHeaderTest и использовал SSMS с выводом результатов в текст, а затем немного отредактировал, чтобы было удобнее для блога:

DBCC FILEHEADER ('FileHeaderTest', 1);
GO

FileId                : 1
LogicalName           : FileHeaderTest
BindingId             : D30AE3EF-14A6-47D5-B267-96F38238D882
FileGroup             : 1
Size                  : 152
MaxSize               : -1
MinSize               : 152
UserShrinkSize        : -1
Growth                : 128
BackupLSN             : 0
RedoStartLSN          : 0
FirstLSN              : 0
MaxLSN                : 0
FirstUpdateLSN        : 0
CreateLSN             : 0
SectorSize            : 512
RecoveryForkGUID      : 00000000-0000-0000-0000-000000000000
RecoveryForkLSN       : 0
DifferentialBaseLsn   : 19000000048800037
DifferentialBaseGuid  : 279A8EF4-4431-4CA5-8939-F613E5BC3033
Status                : 2
RestoreStatus         : 0
ReadOnlyLsn           : 0
ReadWriteLsn          : 0
MaxLsnBranchId        : 00000000-0000-0000-0000-000000000000
RedoTargetPointLsn    : 0
RedoTargetPointGuid   : 00000000-0000-0000-0000-000000000000
RestoreDiffBaseLsn    : 0
RestoreDiffBaseGuid   : 00000000-0000-0000-0000-000000000000
RestorePathOriginLsn  : 0
RestorePathOriginGuid : 00000000-0000-0000-0000-000000000000
OldestRestoredLsn     : 0

Здесь много любопытных вещей, например:

  • BindingId: используется, чтобы убедиться, что файл действительно принадлежит этой базе данных;
  • SectorSize: размер сектора диска;
  • Status: тип файла и его состояние (например, 2 = обычный дисковый файл);
  • различные размеры в количестве 8КБ страниц (например, MaxSize равный −1 означает, что рост файла не ограничен);
  • Growth: на сколько страниц увеличивать файл, если в поле Status НЕ установлен бит 0x100000. Если установлен, то Growth задаётся в процентах.

За изменениями можно наблюдать. Например, если изменить рост файла на 10%:

ALTER DATABASE FileHeaderTest MODIFY FILE (NAME = FileHeaderTest, FILEGROWTH = 10%);
GO

А затем снова вывести содержимое страницы заголовка файла, то поля Status и Growth изменятся на:

.
.
Growth                : 10
.
.
Status                : 1048578
.
.

Что если страница заголовка файла повреждена? Я повредил страницу заголовка файла своей базы и затем запустил SQL Server.

USE FileHeaderTest;
GO

Msg 945, Level 14, State 2, Line 1
Database 'FileHeaderTest' cannot be opened due to inaccessible files or insufficient
memory or disk space. See the SQL Server errorlog for details.

Попробуем режим EMERGENCY:

ALTER DATABASE FileHeaderTest SET EMERGENCY;
GO

Msg 5172, Level 16, State 15, Line 1
The header for file 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\FileHeaderTest.mdf'
is not a valid database file header. The PageAudit property is incorrect.

В таком случае ничего другого не остаётся, кроме как восстанавливаться из резервных копий, а база данных недоступна потому, что файловую группу PRIMARY не удалось поднять онлайн. Если повреждение в файле из вторичной файловой группы, ситуация несколько иная. Я добавил вторичную файловую группу с одним файлом (под именем CorruptFile) и повредил его страницу заголовка. После запуска SQL Server поведение такое же — но на этот раз мы можем перевести файл в офлайн и работать с остальной частью базы данных. Это называется частичной доступностью базы данных и поддерживается только в редакциях Enterprise (и Developer).

ALTER DATABASE FileHeaderTest MODIFY FILE (NAME = CorruptFile, OFFLINE);
GO

Учтите, что единственный способ вернуть офлайн‑файл обратно онлайн — восстановить его из резервной копии. Ещё один тип повреждений, который можно исправить только с помощью бэкапов…




Комментариев нет:

Отправить комментарий