How to move databases configured for SQL Server AlwaysOn
This article describes how to change the location of the data files and the log files for any Microsoft SQL Server 2012 database which are configured with SQL Server AlwaysOn with minimal downtime.
Considerations
We have three node windows 2008/2012 cluster where SQL server is installed and configured for AlwaysOn. The location of AlwaysOn databases on all the three nodes are similar (C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Data). You run out of disk space on drive C:\ and decide to move the physical file of AlwaysOn to a new drive (D:\data\).
Node1 –Default instance (Primary replica)
Node2 –Default instance (Secondary replica –Synchronous)
Node3 –Default instance (Secondary replica –Asynchronous)
One of the solutions to accomplish this is completely remove the AlwaysOn configuration and reconfigure with the new location. But this process is time consuming and requires a lot of downtime. To overcome this we can follow the below steps which would minimise the downtime required to complete the relocation of database files.
Benefits
· Downtime time is time required for two failovers for any number of replicas.
· Downtime is only for application/users using that databases (unlike SQL instance restart that means downtime for applications/users using remaining databases too).
Prerequisites
use < database_name>
go
sp_helpfile
Note: - We have seen scenarios where this doesn’t work on RTM version. So please upgrade the SQL instance with Service pack 1 before following this article
Planned Relocation Practice
1. Disable read-only access for all the secondary replicas.
2. Modify the location of the data and transaction log files on all the replicas using the ALTER DATABASE…MODIFY FILE option.
3. Perform the failover of AlwaysOn group to any synchronous replica (Node2 in this scenario).
Note: This would clear all the file handles on the secondary replicas. On the new primary replica the database files will be used from the original location which can be verified using SP_HELPDB < DBNAME>.
4. Move the physical files (MDF/LDF/NDF) to the new location on all the secondary replicas.
Note: At this point the synchronization between the replicas are broken.
5. Initiate the database recovery using ALTER DATABASE…SET ONLINE on all the secondary replicas to resume the synchronization.
6. Perform the failover of AlwaysOn group back to original node (From Node2 to Node1 in this scenario).
7. Follow the step-4 & step-5 on the Node2 to fix the file location and resume the synchronization.
8. Finally enable the read-only access for all the secondary replicas.
AlwaysOn Group is online as before and the data files & transaction log files are moved to the new location.
Example
The following example moves the AdventureWorks2012 data file and log file to a new location as part of a planned relocation.
Environment:
AlwaysOn Database – AdventureWorks2012
Data file location: C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Data\AdventureWorks2012.mdf
Log file location : C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Data\AdventureWorks2012.ldf
--- YOU MUST EXECUTE THE FOLLOWING SCRIPT IN SQLCMD MODE.
--- Select “QUERY” from the “MENU” bar and select “SQLCMD MODE”
--Disable read-only access for all the secondary replicas
:Connect NODE1
USE [master]
GO
ALTER AVAILABILITY GROUP [AdventureWorksAG] MODIFY REPLICA ON N'NODE1' WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = NO))
ALTER AVAILABILITY GROUP [AdventureWorksAG] MODIFY REPLICA ON N'NODE2' WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = NO))
ALTER AVAILABILITY GROUP [AdventureWorksAG] MODIFY REPLICA ON N'NODE3' WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = NO))
--Modify the location of the data and transaction log files on all the replicas
ALTER DATABASE [AdventureWorks] MODIFY FILE (NAME='AdventureWorks',FILENAME='C:\DATA\AdventureWorks.mdf')
ALTER DATABASE [AdventureWorks] MODIFY FILE (NAME='AdventureWorks_log',FILENAME='C:\DATA\AdventureWorks_log.ldf')
:Connect NODE2
:Connect NODE3
--Perform the failover of AlwaysOn group
ALTER AVAILABILITY GROUP [AdventureWorksAG] FAILOVER;
--Move the physical files (MDF/LDF/NDF) to the new location on all the secondary replicas.
--Enable XP_CMDSHELL
sp_configure 'show advanced options',1
reconfigure
sp_configure 'xp_cmdshell',1
--MOVE FILES
xp_cmdshell 'move "C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Data\AdventureWorks*.*" C:\data\'
--Disable XP_CMDSHELL
--Initiate the database recovery
ALTER DATABASE [AdventureWorks] SET ONLINE
--Perform the failover of AlwaysOn group back to original node
--To fix the file location and resume the synchronization on Node2
--Finally enable the read-only access for all the secondary replicas
ALTER AVAILABILITY GROUP [AdventureWorksAG] MODIFY REPLICA ON N'NODE1' WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL))
ALTER AVAILABILITY GROUP [AdventureWorksAG] MODIFY REPLICA ON N'NODE2' WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL))
ALTER AVAILABILITY GROUP [AdventureWorksAG] MODIFY REPLICA ON N'NODE3' WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL))
References
ALTER DATABASE (Transact-SQL)
BACKUP (Transact-SQL)
RESTORE (Transact-SQL)
Author:
Raghavendra Srinivasan , Support Engineer, Microsoft India GTSC
Reviewed by:
Karthick Krishnamurthy, Technical Advisor, Microsoft India GTSC
Didn't you say you were moving the files to D:\Data ?
The script appears to read like it would move the files to C:\Data.
Hi Expert, Thanks for posting so nice article, I got following error when Initiated the database recovery,
1> USE master
2> GO
Changed database context to 'master'.
1> ALTER DATABASE [MSCRM_CONFIG] SET ONLINE
Msg 1468, Level 16, State 5, Server CRM-01, Line 1
The operation cannot be performed on database "MSCRM_CONFIG" because it is involved in a database mirroring session or an availability group. Some operations are not allowed on a database that is participating in a database mirroring session or in an availability group.
Msg 5069, Level 16, State 1, Server CRM-01, Line 1
ALTER DATABASE statement failed.
Any help would be appreciated.
Thanks & Regards
Nice article Rags. I noticed some typos though. In all the places where you're disabling XP_Cmdshell, you're setting it to 1, not 0. For example:
sp_configure 'xp_cmdshell',1 ---this should be 0, not 1