page contents

About the Post

Author Information

How to: Move SQL Databases (User)

This is an article that I have been meaning to write for a while and I just got motivated writing it after reading Erik Darling‘s article Moving Databases with ALTER DATABASE. I wrote my rough draft in an earlier article (that I ended up putting up on my site) on how to move system databases in SQL Server 2008R2. In this feature, I will talk about moving user databases in all versions (since they are using the same manner in currently supported SQL versions today) and then another article about moving systems databases. (in SQL Server 2008 and later)

As you know, things change from time to time and that is especially true with database administration. The data in the database is always needed, but the resources where this data resides may change. For example, a LUN might not be able to expand to present more capacity, a server might be old and needs to be retired or other reasons along this line of thought. The end result is that these data files will need to migrate to a different storage device to allow the system to keep presenting the information. Which leads to the question of how do you perform this task?

I attempted to explain this in earlier articles using the correct method (which pointed to a script you could download from David Levy Blog | Twitter) and an older line of thought that is not recommended. In that earlier article, I was talking about moving databases by detaching / reattaching databases, but that is just too risky as it could lead to data corruption. There might be queries still in the transaction log that have yet to be processed or an active running query that is still running. So forcibly taking a database offline by using the detach approach is not the right line of attack.

The proper way to proceed is to use the ALTER DATABASE method and that is the road I am going down.

As usual, before you begin any modifications with SQL Server, make sure you have adequate backups, in case something goes wrong. You will need to also verify that the backup you took is working by performing a test. Restore it to another instance and then query it to confirm the results are accurate. No one will take responsibility for what happens to your data files as that burden lies on your shoulders.

In this post, I will start with moving the user database.

In my instance, I am using SQL Server 2008R2 and I am using an older installed from the AdventureWorks sample database that will installed the data files on the C drive. (The current download – AdventureWorks Databases 2012, 2008R2 and 2008 provides a data file that you can attach with a SQL command)

Here is a screenshot of my SQL Server properties for the database settings (notice below how the installer will ignore it)


Here is a same screenshot of my data files on the drives:


Notice that the system databases are located on the C drive. It ignored the way that I wanted to install them on my H drive and O Drive, which is how I configured the server.

E- Backup Drive
H- Data Drive
O- Traansaction Logs
T- TempDB Data Drive

Now I am going to use that installer to mount the databases by just double clicking the executable. It presents this menu as seen below, but as you can tell there is nothing to configure during this install


After the install is done, here are the databases and they are all located on the C drive


 

 

 

 

 

 

 

 

 

The first step is to verify the data files and locations by using this script:

/*

To find the current logical and physical database file names:

SYNTAX: USE Database_name EXEC sp_helpfile

*/


USE AdventureWorks

EXEC sp_helpfile

USE AdventureWorksDW

EXEC sp_helpfile

USE AdventureWorksLT

EXEC sp_helpfile

USE AdventureWorksLT2008R2

EXEC sp_helpfile

USE AdventureWorksDW2008R2

EXEC sp_helpfile

Here are the database view and script in my SSMS window:


Here are my results from executing that query:


Now I need to modify the SQL data files to change to their new locations:

-- Move User Database mdf to new file location

ALTER DATABASE AdventureWorks MODIFY FILE ( NAME = AdventureWorks_Data, FILENAME
= 'H:\Program Files\MSSQL10_50.MSSQLSERVER\MSSQL\Data\AdventureWorks_Data.mdf');

ALTER DATABASE AdventureWorksDW MODIFY FILE ( NAME = AdventureWorksDW_Data, FILENAME
= 'H:\Program Files\MSSQL10_50.MSSQLSERVER\MSSQL\Data\AdventureWorksDW_Data.mdf');

ALTER DATABASE AdventureWorksLT MODIFY FILE ( NAME = AdventureWorksLT_Data, FILENAME
= 'H:\Program Files\MSSQL10_50.MSSQLSERVER\MSSQL\Data\AdventureWorksLT_Data.mdf');

ALTER DATABASE AdventureWorksLT2008R2 MODIFY FILE ( NAME =AdventureWorksLT2008R2_Data, FILENAME
= 'H:\Program Files\MSSQL10_50.MSSQLSERVER\MSSQL\Data\AdventureWorksLT2008R2_Data.mdf');

ALTER DATABASE AdventureWorksDW2008R2 MODIFY FILE ( NAME = AdventureWorksDW2008R2_Data, FILENAME
= 'H:\Program Files\MSSQL10_50.MSSQLSERVER\MSSQL\Data\AdventureWorksDW2008R2_Data.mdf');

-- Move User Database ldf to new log location

ALTER DATABASE AdventureWorks MODIFY FILE ( NAME = AdventureWorks_Log, FILENAME
= 'O:\Program Files\MSSQL10_50.MSSQLSERVER\MSSQL\TLogs\AdventureWorks_Log.ldf');

ALTER DATABASE AdventureWorksDW MODIFY FILE ( NAME = AdventureWorksDW_Log, FILENAME
= 'O:\Program Files\MSSQL10_50.MSSQLSERVER\MSSQL\TLogs\AdventureWorksDW_Log.ldf');

ALTER DATABASE AdventureWorksLT MODIFY FILE ( NAME = AdventureWorksLT_Log, FILENAME
= 'O:\Program Files\MSSQL10_50.MSSQLSERVER\MSSQL\TLogs\AdventureWorksLT_Log.ldf');

ALTER DATABASE AdventureWorksLT2008R2 MODIFY FILE ( NAME = AdventureWorksLT2008R2_Log, FILENAME
= 'O:\Program Files\MSSQL10_50.MSSQLSERVER\MSSQL\TLogs\AdventureWorksLT2008R2_Log.ldf');

ALTER DATABASE AdventureWorksDW2008R2 MODIFY FILE ( NAME = AdventureWorksDW2008R2_Log, FILENAME
= 'O:\Program Files\MSSQL10_50.MSSQLSERVER\MSSQL\TLogs\AdventureWorksDW2008R2_Log.ldf');

Here is the result of that query:


Now you need to confirm that the results are correctly by running the first SQL query to verify the data files and locations:


Now I need to take the databases offline:

/*

This is the part that you need to think through. People have to be cool with the database being offline while you move the physical file. This is not a seamless transition. If you're moving large enough databases, you may want to consider an alternate method, like Mirroring or Log Shipping. They take more work, but you get the whole near-zero-downtime thing out of it. You may want to stage a mock file move to test LUN to LUN copy speeds. See how many GB you can move per minute. That way you'll at least be able to estimate how long the outage will last. Assuming all that is cool, go ahead and take the database offline.

*/

ALTER DATABASE AdventureWorks SET OFFLINE;

ALTER DATABASE AdventureWorksDW SET OFFLINE;

ALTER DATABASE AdventureWorksLT SET OFFLINE;

ALTER DATABASE AdventureWorksLT2008R2 SET OFFLINE;

ALTER DATABASE AdventureWorksDW2008R2 SET OFFLINE;

Now you need to copy the files either with a script (preferably one with a progress bar) or using Windows Explorer, then you will need to bring the databases online. Then you can check to see if all is well (in addition to seeing the databases come online)

 

-- Verify the file change by running the following query.

SELECT name, physical_name AS CurrentLocation, state_desc

FROM sys.master_files

WHERE database_id in (DB_ID(N'AdventureWorks'),DB_ID(N'AdventureWorksDW'),DB_ID(N'AdventureWorksLT'),

DB_ID(N'AdventureWorksLT2008R2'),DB_ID(N'AdventureWorksDW2008R2'));

GO

The results confirm the expectations that we wanted to see:


Here are the files now after the changes we just made:


The next article will cover moving system databases (Master, Model, MSDB and TempDB) for SQL Server 2008R2, 2012, and 2014.

Tags: , , , , , , , , ,

Comments are closed.

Copy Protected by Chetan's WP-Copyprotect.