Ошибка 5161 - An unexpected file id was encountered. File id %d was expected but %d was read from "%.*ls". Verify that files are mapped correctly in sys.master_files. ALTER DATABASE can be used to correct the mappings.
может возникнуть, когда вы пытаетесь подменить файлы БД.
Сценарий: у вас есть в наличии физические файлы базы данных (например, перенесены с другого сервера после краха) и вам нужно эти файлы подключить к серверу. Основной порядок действий в этом случаи может быть следующий:
- Создать новую БД с аналогичной структурой
- С помощью операции ALTER DATABASE ... MODIFY FILE указать расположение файлов, которые нам нужно "подцепить"
- Перезапуск SQL Server
После этого, вместо того, чтобы получить доступ к данным, ваша БД переходит в статус Recovery Pending.
Если посмотреть журнал ошибок SQL Server, то там могут присутствовать ошибки:
Причина этой ошибки в том, что файлы вашей исходной БД имели другие идентификаторы, например:
А когда вы создаёте пустую БД, то файлы идут по порядку:
CREATE DATABASE [MyDB]
ON PRIMARY
( NAME = N'db', FILENAME = N'c:\temp\db\db.MDF' ),
( NAME = N'FG_01', FILENAME = N'c:\temp\db\01.ndf' ),
( NAME = N'FG_02', FILENAME = N'c:\temp\db\02.ndf' ),
( NAME = N'FG_03', FILENAME = N'c:\temp\db\03.ndf' ),
( NAME = N'FG_04', FILENAME = N'c:\temp\db\04.ndf' ),
( NAME = N'FG_05', FILENAME = N'c:\temp\db\05.ndf' ),
( NAME = N'FG_06', FILENAME = N'c:\temp\db\06.ndf' )
LOG ON
( NAME = N'db_log', FILENAME = N'c:\temp\db\db_Log.LDF' )
go
Если попытаться "подсунуть" файлы нужной БД на место текущих, то мы получим ошибку, озвученную выше. Для того, чтобы её избежать необходимо убедиться, что порядок файлов в sys.master_files соответствует, тому, что указан внутри системной таблицы sys.sysprufiles (object_id = 24), которая хранится в mdf-файле.
Самый простой сценарий для подключения файлов в такой БД:
--Создание пустой БД
create DATABASE [MyDB]
ON PRIMARY
( NAME = N'db', FILENAME = N'c:\temp\db\db.MDF' ),
--2 файла для подмены
( NAME = N'FG_xx1', FILENAME = N'c:\temp\db\xx1.ndf' ),
( NAME = N'FG_xx2', FILENAME = N'c:\temp\db\xx2.ndf' ),
---------------------
( NAME = N'FG_01', FILENAME = N'c:\temp\db\01.ndf' ),
( NAME = N'FG_02', FILENAME = N'c:\temp\db\02.ndf' ),
( NAME = N'FG_03', FILENAME = N'c:\temp\db\03.ndf' ),
( NAME = N'FG_04', FILENAME = N'c:\temp\db\04.ndf' ),
( NAME = N'FG_05', FILENAME = N'c:\temp\db\05.ndf' ),
( NAME = N'FG_06', FILENAME = N'c:\temp\db\06.ndf' )
LOG ON
( NAME = N'db_log', FILENAME = N'c:\temp\db\db_Log.LDF' );
go
--теперь можно эти файлы удалить
alter database [MyDB] remove file FG_xx1;
go
alter database [MyDB] remove file FG_xx2;
go
--Указываем новое расположение файлов (файлы, которые необходимо подключить)
ALTER DATABASE MyDB
MODIFY FILE (NAME = db, FILENAME = N'c:\temp\db\new\db.MDF');
go
ALTER DATABASE MyDB
MODIFY FILE (NAME = db_log, FILENAME = N'c:\temp\db\new\db_log.LDF');
GO
ALTER DATABASE MyDB
MODIFY FILE (NAME = FG_01, FILENAME = N'c:\temp\db\new\01.ndf');
GO
ALTER DATABASE MyDB
MODIFY FILE (NAME = FG_02, FILENAME = N'c:\temp\db\new\02.ndf');
GO
ALTER DATABASE MyDB
MODIFY FILE (NAME = FG_03, FILENAME = N'c:\temp\db\new\03.ndf');
go
ALTER DATABASE MyDB
MODIFY FILE (NAME = FG_04, FILENAME = N'c:\temp\db\new\04.ndf');
go
ALTER DATABASE MyDB
MODIFY FILE (NAME = FG_05, FILENAME = N'c:\temp\db\new\05.ndf');
go
ALTER DATABASE MyDB
MODIFY FILE (NAME = FG_06, FILENAME = N'c:\temp\db\new\06.ndf');
go