Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restore SQL Database with Replace option

Tags:

sql-server

I am trying to understand the REPLACE option from various sources and have not clarified myself. I am using SQL Server 2014 version.

What is the difference between below 2 queries? Both are completing without any error. With and Without Replace.

USE [master]
RESTORE DATABASE [Test] FROM  DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Backup\MyDatabase.bak'
WITH FILE = 3,  NOUNLOAD,  STATS = 5
GO

Vs

USE [master]
RESTORE DATABASE [Test] FROM  DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Backup\MyDatabase.bak'
WITH REPLACE, FILE = 3,  NOUNLOAD,  STATS = 5
GO

When I try to Replace with the .mdf and .ldf of an existing database (Test2), I get an error. My understanding so far is that I can restore the backup of [Test1] db with the name [Test2] (This already exists in my server and Test1 DB also exists).

I got the statement for REPLACE "Restoring over an existing database with a backup taken of another database." from one of Microsoft Link.

USE [master]
RESTORE DATABASE [Test2] FROM  DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Backup\MyDatabase.bak'
WITH REPLACE, FILE = 3,  NOUNLOAD,  STATS = 5
GO

Error:

Msg 1834, Level 16, State 1, Line 2
The file 'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\test1.mdf' cannot be overwritten.  It is being used by database 'test1'.
Msg 3156, Level 16, State 4, Line 2
 'test1' cannot be restored to 'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\test1.mdf'. Use WITH MOVE to identify a valid location for the file.
Msg 1834, Level 16, State 1, Line 2

What is the purpose of the REPLACE option and what it replaces behind the scene. Can any one please explain with any example?

like image 513
p2k Avatar asked Aug 25 '16 08:08

p2k


2 Answers

The purpose of the REPLACE option is to allow you to overwrite a database name (clobber an existing database with a different name from the backup). Your errors are caused by you trying to overwrite the files of another database from the one you asked to restore over. So restoring over Test2 database but clobbering Test1 database files (Test1.MDB and Test1.LDB). If you don't use the MOVE clause then the RESTORE command will use the same filenames as the BACKUP. Probably not a good idea otherwise things are going to get pretty confusing. (Test2 database pointing to Test1.mdb and Test1.ldb)

My script below demonstrates the issue. I create database Test1. I Back it up. I try to restore it to Test2 using REPLACE. It fails, because Test1.mdb and Test1.ldb are being used by the Test1 database. I drop the Test1 database. I try to restore it to Test2 using REPLACE and it now works. (But is using Test1.mdb and Test1.ldb).

CREATE DATABASE [Test1]
 ON  PRIMARY 
( NAME = N'Test1', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\Test1.mdf' , SIZE = 8192KB , FILEGROWTH = 65536KB )
 LOG ON 
( NAME = N'Test1_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\Test1_log.ldf' , SIZE = 8192KB , FILEGROWTH = 65536KB )
GO
BACKUP DATABASE [Test1] TO  DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\Test1.bak' WITH  COPY_ONLY, NOFORMAT, NOINIT,  NAME = N'Test1-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
GO
--Fails... It is being used by database 'Test1'.
RESTORE DATABASE [Test2] FROM  DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\Test1.bak'
WITH REPLACE,   NOUNLOAD,  STATS = 5
GO
DROP DATABASE Test1
GO
--Now works, but the files are Test1.mdf and Test1.ldf
RESTORE DATABASE [Test2] FROM  DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\Test1.bak'
WITH REPLACE,   NOUNLOAD,  STATS = 5
GO
DROP DATABASE Test2
GO
CREATE DATABASE [Test2]
 ON  PRIMARY 
( NAME = N'Test1', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\Test2.mdf' , SIZE = 8192KB , FILEGROWTH = 65536KB )
 LOG ON 
( NAME = N'Test1_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\Test2_log.ldf' , SIZE = 8192KB , FILEGROWTH = 65536KB )
GO
--Now the same command works,  because Test1.mdf and Test1.ldf are not in use.
RESTORE DATABASE [Test2] FROM  DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\Test1.bak'
WITH REPLACE,   NOUNLOAD,  STATS = 5
GO

This is Microsoft's explanation of the REPLACE option:

https://docs.microsoft.com/en-us/sql/t-sql/statements/restore-statements-transact-sql?view=sql-server-2017#REPLACEoption

REPLACE Option Impact REPLACE should be used rarely and only after careful consideration. Restore normally prevents accidentally overwriting a database with a different database. If the database specified in a RESTORE statement already exists on the current server and the specified database family GUID differs from the database family GUID recorded in the backup set, the database is not restored. This is an important safeguard.

The REPLACE option overrides several important safety checks that restore normally performs. The overridden checks are as follows:

Restoring over an existing database with a backup taken of another database.

With the REPLACE option, restore allows you to overwrite an existing database with whatever database is in the backup set, even if the specified database name differs from the database name recorded in the backup set. This can result in accidentally overwriting a database by a different database.

Restoring over a database using the full or bulk-logged recovery model where a tail-log backup has not been taken and the STOPAT option is not used.

With the REPLACE option, you can lose committed work, because the log written most recently has not been backed up.

Overwriting existing files.

For example, a mistake could allow overwriting files of the wrong type, such as .xls files, or that are being used by another database that is not online. Arbitrary data loss is possible if existing files are overwritten, although the restored database is complete.

like image 166
Mincho Avatar answered Oct 10 '22 15:10

Mincho


The way I found is like following:

  • Bring your database offline -> tasks-> bring it offline
  • Go to your Database in the Windows Explorer and delete your mdf and log.ldf
    • C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\Test1.mdf
  • Let your Sql script run

That's it.

In general I think it is better to create a backup and restore this. In the database.

  • right click on database -> Tasks -> Take Offline
  • right click on database -> Tasks -> Restore -> Database
  • Select a Page -> General -> chose your file under device
  • Select a Page -> Options -> mark Overwrite the existing database (with replace)
  • Let it run
like image 29
Fredy Avatar answered Oct 10 '22 14:10

Fredy