Writing about SQL Server for close to 8 years, almost every single day means I get a lot of questions from people on a daily basis. Though I try to answer as many as possible (via email, blog, twitter and Facebook), I get many interesting questions. There are a variety of questions ranging from installation, scalability, performance, TSQL, new feature and a variety of error messages. Recently I got an email which had below the question:
I was given task to move the files for few databases and also to rename them. While doing this activity I did some mistake and few of my databases are not coming online. Here is the error I am getting for those databases.
2014-10-20 17:52:39.08 spid37s Error: 5173, Severity: 16, State: 1.
2014-10-20 17:52:39.08 spid37s One or more files do not match the primary file of the database. If you are attempting to attach a database, retry the operation with the correct files. If this is an existing database, the file may be corrupted and should be restored from a backup.
2014-10-20 17:52:39.08 spid37s Log file ‘E:\Program Files\Microsoft SQL Server\MSSQL12.SQL2014\MSSQL\DATA\SQLAuth_log.ldf’ does not match the primary file. It may be from a different database or the log may have been rebuilt previously.
Can you please help me how I can resolve this issue and what needs to be done to mitigate?
On further investigation of ERRORLOG it was found that we have “RECOVERY_PENDING” state for the database because recovery of database could not be complete. The cause of the error is all files which are getting used by database don’t belong to the same database. There is a safety mechanism in the database startup where it checks whether all files below to same database. This is so very important because we don’t want to override existing files inadvertently.
It is not possible to open and read the files to find out information about MDF files when it is attached. We can use DBCC CHECKPRIMARYFILE command to read the primary file header to know the information stored. Here is the quick demo of various parameters and the output. I have found this quite powerful and thought was worth a share.
First, let’s create the database with two data files and one log file.
CREATE DATABASE [SQLAuthority] ON PRIMARY
(NAME = N'SQLAuthority_MDF', FILENAME = N'C:\Temp\SQLAuthority_MDF.mdf'),
(NAME = N'SQLAuthority_NDF', FILENAME = N'C:\Temp\SQLAuthority_NDF.ndf')
(NAME = N'SQLAuthority_log', FILENAME = N'C:\Temp\SQLAuthority_log.ldf')
Let us detach the database using the following command:
Now let’s use DBCC CHECKPRIMARYFILE to read file header and get details.
We would see “1” and output only for first file because that’s the primary data file. Let’s run the same command with other parameters and check the output.
As we can see that by using the command we can read the header of the file and get various properties of primary files.
- Option 1: File IDs, filegroup id, logical name, physical name for other files belonging to same database.
- Option 2: Which database this file belongs to, what was the database version and collation.
- Option 3 is subset of option 1
This doesn’t mean that we can use two different files of same database taken from different servers and attach them. Sometime this command is useful when you don’t know the logical file names of the files which you have got and want to use the file (when attach is not working due to corruption).
Hope this was an interesting option and you were able to learn something from it as I did when first using the same.
Reference: Pinal Dave (https://blog.sqlauthority.com)