This was a question from the MSDN Disaster Recovery forum I started while I was at Microsoft. I have a 600 gig database that has a mirror. I need to move the databases from local drives to a SAN. Can anyone recommend a document that lists the steps to go through to move both the principle and mirror to the SAN with no down time? or minimal down time? As far as I know, there isn’t any such document so I had a crack at coming up with a list of operations. Here’s what I had: And I promised to try it out to make sure I had it right so in this blog post I’m going to walk through the steps of doing this. It turns out that the steps above are slightly incorrect. Step 6 above doesn’t work because the database is in recovery (so is inaccessible) and there’s a short-cut when moving the database on the first node to avoid having to take and copy more backups. Let’s see how it works and I’ll post the corrected sequence at the end. As I did in yesterday’s mirroring post, I’m going to use the TicketSalesDB database from our Always-On DVDs. It’s only a few hundred MB instead of 600GB but the principal is the same (no pun intended :-)). I’ve got mirroring running between two nodes, SQLDEV01 (the principal) and SQLDEV02 (the mirror), both of which are running 2005 SP2 and I’ve got a simulated workload inserting rows into the database. I don’t actually have a SAN laying around so I’m cheating and I have directories called C:\SQLDEV01SAN and C:\SQLDEV02SAN instead. It’s the location change that’s the interesting part, not where the actual location is. Step 1 On SQLDEV01, take a full backup and a log backup: BACKUP
DATABASE TicketSalesDB TO DISK = ‘C:\SQLskills\TicketSalesDB.BAK’ WITH INIT;
GO
BACKUP
LOG TicketSalesDB TO DISK = ‘C:\SQLskills\TicketSalesDB_Log.bak’ WITH INIT;
GO
Step 2
On SQLDEV01, break the mirroring partnership:
ALTER
DATABASE TicketSalesDB SET PARTNER OFF;
GO
And just check that it’s gone:
SELECT
mirroring_state_desc FROM sys.database_mirroring WHERE database_id = DB_ID (‘TicketSalesDB’);
GO
which returns:
NULL
Step 3
On SQLDEV02, drop the mirror database – this wouldn’t work unless mirroring was no longer running:
DROP
DATABASE TicketSalesDB;
GO
Step 4
Copy the backups to SQLDEV02 and restore them on the SAN and remembering to use WITH NORECOVERY:
RESTORE
DATABASE TicketSalesDB FROM DISK=‘C:\SQLskills\TicketSalesDB.bak’
WITH
MOVE ‘TicketSalesDBData’ TO ‘C:\SQLDEV02SAN\TicketSalesDBData.MDF’,
MOVE ‘TicketSalesFG2005Q1′ TO ‘C:\SQLDEV02SAN\TicketSalesFG2005Q1.NDF’,
MOVE ‘TicketSalesFG2005Q2′ TO ‘C:\SQLDEV02SAN\TicketSalesFG2005Q2.NDF’,
MOVE ‘TicketSalesFG2005Q3′ TO ‘C:\SQLDEV02SAN\TicketSalesFG2005Q3.NDF’,
MOVE ‘TicketSalesFG2005Q4′ TO ‘C:\SQLDEV02SAN\TicketSalesFG2005Q4.NDF’,
MOVE ‘TicketSalesDBLog’ TO ‘C:\SQLDEV02SAN\TicketSalesDBLog.LDF’,
NORECOVERY;
GO
RESTORE
LOG TicketSalesDB FROM DISK = ‘C:\SQLskills\TicketSalesDB_Log.bak’ WITH NORECOVERY;
GO
Step 5
On SQLDEV02, set the mirroring partner to be SQLDEV01:
ALTER
DATABASE TicketSalesDB SET PARTNER = ‘TCP://SQLDEV01:5091′;
GO
Step 6
On SQLDEV01, start mirroring:
ALTER
DATABASE TicketSalesDB SET PARTNER = ‘TCP://SQLDEV02:5092′;
GO
And check that it’s running:
SELECT
mirroring_state_desc FROM sys.database_mirroring WHERE database_id = DB_ID (‘TicketSalesDB’);
GO
This time it returns:
SYNCHRONIZED
Step 7
Now we need to failover so that we can move the database on SQLDEV01 onto its SAN. Before we do that, let’s make sure that SQLDEV01 is the principal:
SELECT
mirroring_role_desc FROM sys.database_mirroring WHERE database_id = DB_ID (‘TicketSalesDB’);
GO
which returns:
PRINCIPAL
Now force the failover:
ALTER
DATABASE TicketSalesDB SET PARTNER FAILOVER;
GO
And query the DMV again to make sure. This time the mirroring_state_desc returned is:
MIRROR
Excellent!
Now, I did all of this while my workload was running and it automatically failed over to SQLDEV02, with the database now hosted on the SAN. To do the same move on SQLDEV01, we don’t need to go through the backup and copy process again – we can just use the original backups we took in step 1.
Step 8
We need to break the mirroring partnership again, this time executing on SQLDEV02, the new principal:
ALTER
DATABASE TicketSalesDB SET PARTNER OFF;
GO
On SQLDEV01, we can now drop the database and restore the original backups onto the SAN:
DROP DATABASE TicketSalesDB;
GO
RESTORE
DATABASE TicketSalesDB FROM DISK=‘C:\SQLskills\TicketSalesDB.bak’
WITH
MOVE ‘TicketSalesDBData’ TO ‘C:\SQLDEV01SAN\TicketSalesDBData.MDF’,
MOVE ‘TicketSalesFG2005Q1′ TO ‘C:\SQLDEV01SAN\TicketSalesFG2005Q1.NDF’,
MOVE ‘TicketSalesFG2005Q2′ TO ‘C:\SQLDEV01SAN\TicketSalesFG2005Q2.NDF’,
MOVE ‘TicketSalesFG2005Q3′ TO ‘C:\SQLDEV01SAN\TicketSalesFG2005Q3.NDF’,
MOVE ‘TicketSalesFG2005Q4′ TO ‘C:\SQLDEV01SAN\TicketSalesFG2005Q4.NDF’,
MOVE ‘TicketSalesDBLog’ TO ‘C:\SQLDEV01SAN\TicketSalesDBLog.LDF’,
NORECOVERY;
GO
RESTORE
LOG TicketSalesDB FROM DISK = ‘C:\SQLskills\TicketSalesDB_Log.bak’ WITH NORECOVERY;GO
And setup mirroring again. On SQLDEV01:
ALTER
DATABASE TicketSalesDB SET PARTNER = ‘TCP://SQLDEV02:5092′;
GO
And on SQLDEV02:
ALTER
DATABASE TicketSalesDB SET PARTNER = ‘TCP://SQLDEV01:5091′;
GO
And we’re running again.
Step 9
Now all we need to do is fail the workload back to SQLDEV01 by executing this on SQLDEV02:
ALTER
DATABASE TicketSalesDB SET PARTNER FAILOVER;
GO
Summary
So – the corrected sequence for moving a database while mirroring is running is the following:
- Take a full backup of the principal database on node A, and the required log backup
- Break the mirroring partnership
- Drop the current mirror database on node B
- Copy the backups to node B and restore it on the SAN on node B using WITH NORECOVERY, remembering to use WITH MOVE to place the files correctly
- Setup the mirroring partnership to point to the newly restored database on the SAN on node B
- Start mirroring and the new mirror will catch-up
- Failover to the mirror on node B, which becomes the new principal
- Follow the same procedure to move the new mirror on node A onto its SAN, but using the original backups from step 1
- Failback
Hope this helps.
3 Responses to Search Engine Q&A #2: Moving a database while Database Mirroring is running
Excellent! Thank you very much for the help. I will move my 600 db tonight.
deb
[...] How to move a database while database mirroring is running [...]
[...] resources? A5) Blog posts… SQL Server 2008: Automatic Page Repair with Database Mirroring Search Engine Q&A #2: Moving a database while Database Mirroring is running SQL Server 2008: New Performance Counters for Database Mirroring Search Engine Q&A #3: Database [...]