In the past, I have written about attaching data files to a SQL Server instance when log files are missing by the use of the FOR ATTACH_REBUILD_LOG clause of the CREATE DATABASE statement. Recently, I was referring the CREATE DATABASE documentation on MSDN. It’s a comprehensive document and and the following line for read-only databases caught my attention.
For a read-only database, the log cannot be rebuilt because the primary file cannot be updated. Therefore, when you attach a read-only database with a log that is unavailable, you must provide the log files, or the files in the FOR ATTACH clause.
This statement was contrary to what I had observed before. Hence, I decided to re-validate the findings via a demo.
The first step, of course is to create a database.
USE [master]; GO CREATE DATABASE ReadOnlyDBForAttach ON PRIMARY (NAME = ReadOnlyDBForAttach_Data, FILENAME='C:\SQLData\MSSQL12.SQL2014\MSSQL\DATA\ReadOnlyDBForAttach_Data.mdf'), FILEGROUP RODefault (NAME = ReadOnlyDBForAttach_RODefault, FILENAME='C:\SQLData\MSSQL12.SQL2014\MSSQL\DATA\ReadOnlyDBForAttach_RODefault.mdf') LOG ON (NAME = ReadOnlyDBForAttach_Log, FILENAME='C:\SQLData\MSSQL12.SQL2014\MSSQL\DATA\ReadOnlyDBForAttach_Log.ldf'); GO
As can be seen from the script referenced above, the database we created as 2 data file groups, one is the default PRIMARY filegroup. Because we cannot make the PRIMARY filegroup READ_ONLY, we will be making the other filegroup (RODefault) READ_ONLY. To add complexity, we will also make it the default filegroup, i.e. any new objects created without specifying a filegroup, it will be created in the filegroup marked as default.
Finally, we will also mark the database as READ_ONLY.
USE [master]; GO ALTER DATABASE ReadOnlyDBForAttach MODIFY FILEGROUP [RODefault] DEFAULT; GO ALTER DATABASE ReadOnlyDBForAttach MODIFY FILEGROUP [RODefault] READ_ONLY; GO ALTER DATABASE ReadOnlyDBForAttach SET READ_ONLY; GO
Now, let us check out the database and filegroup properties.
USE ReadOnlyDBForAttach; GO SELECT 'Database Properties', sd.[name], sd.is_read_only, sd.is_cleanly_shutdown FROM sys.databases AS sd WHERE sd.[name] = 'ReadOnlyDBForAttach'; SELECT 'File properties', sdf.file_id, sdf.type, sdf.data_space_id, sdf.type_desc, sdf.name, sdf.is_read_only, sdf.is_media_read_only FROM sys.database_files AS sdf; GO

Read Only database and database file properties
Now, let us detach the database, and delete the log file. (NOTE: We are removing the log file for the purposes of this demo only. Please do not do this in your QA or production environments).
USE [master]; GO EXEC sp_detach_db @dbname = 'ReadOnlyDBForAttach'; GO

Read Only Database – Log File Removed
Finally, let us attach the database back to the SQL Server instance using the CREATE DATABASE…FOR ATTACH_REBUILD_LOG clause.
USE [master] GO CREATE DATABASE [ReadOnlyDBForAttach] ON PRIMARY ( NAME = N'ReadOnlyDBForAttach_Data', FILENAME = N'C:\SQLData\MSSQL12.SQL2014\MSSQL\DATA\ReadOnlyDBForAttach_Data.mdf') FOR ATTACH_REBUILD_LOG GO
File activation failure. The physical file name "C:\SQLData\MSSQL12.SQL2014\MSSQL\DATA\ReadOnlyDBForAttach_Log.ldf" may be incorrect. New log file 'C:\SQLData\MSSQL12.SQL2014\MSSQL\DATA\ReadOnlyDBForAttach_log.ldf' was created.
As can be seen from the message above, the log file was successfully created and the database was successfully attached to the SQL Server instance.
Let us cross-check the database and file properties again:
USE ReadOnlyDBForAttach; GO SELECT 'Database Properties', sd.[name], sd.is_read_only, sd.is_cleanly_shutdown FROM sys.databases AS sd WHERE sd.[name] = 'ReadOnlyDBForAttach'; SELECT 'File properties', sdf.file_id, sdf.type, sdf.data_space_id, sdf.type_desc, sdf.name, sdf.is_read_only, sdf.is_media_read_only FROM sys.database_files AS sdf; GO

Read Only Database and Data File Properties After Attach
Conclusion
- Contrary to the MSDN remark, a read-only database can be successfully attached to a SQL Server instance even when the log file does not exist by the use of CREATE DATABASE…FOR ATTACH_REBUILD_LOG
- A read-only database becomes a read/write database if it has been attached to the SQL Server using FOR ATTACH_REBUILD_LOG and the log file was rebuilt
My findings above do not agree with the MSDN remark. At the moment, I am inclined to believe that this is a bug in the documentation as I have found a couple of years ago as well (see references). Please do share your views on the same in the post comments.
References/Further Reading
- SQL Server Myth: Log files are removed when a database is made READ_ONLY [Link]
- Creating a database without the log backup file – Error Msg. 5120 [Link]
- CREATE DATABASE…ATTACH_REBUILD_LOG resets database recovery mode to SIMPLE [Link]
- Setting database to READ_ONLY does not change the file-group properties [Link]
- sp_attach_db v/s CREATE DATABASE FOR ATTACH – Number of files limitation; Msg. 8144 (Procedure has too many arguments specified) [Link]
- CREATE DATABASE [MSDN Documentation]
Until we meet next time,
Be courteous. Drive responsibly.