/*============================================================================ File: GenericDatabaseMirroringSetup.sql (a SQLCMD script) Summary: A generic SQLCMD script for setting up Database Mirroring in the High Availability configuration. LOTS of variables to define... be sure to review the entire script before execution. Based on the Database Mirroring Lab - DBM "In Action". Have fun! Date: January 2008 SQL Server Version: 9.00.3054.00 (SP2) ------------------------------------------------------------------------------ Copyright (C) 2008 Kimberly L. Tripp, SYSolutions, Inc. Script provided for sample use. All rights reserved. For more scripts and sample code, check out http://www.SQLskills.com This script is intended only as a supplement to demos and lectures given by SQLskills instructors. THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. ============================================================================*/ :SETVAR PrincipalServer Servername\InstanceName :SETVAR PrincipalDNS FullyQualifiedDNSName :SETVAR PrincipalPort 5091 :SETVAR MirrorServer Servername\InstanceName :SETVAR MirrorDNS FullyQualifiedDNSName :SETVAR MirrorPort 5092 :SETVAR WitnessServer Servername\InstanceName :SETVAR WitnessDNS FullyQualifiedDNSName :SETVAR WitnessPort 5090 :SETVAR Database2Mirror DatabaseName :SETVAR RestoreWithMove TRUE :SETVAR BackupLocation \\servername\sharename\path go -- These are the parameters needed when using the VPC --:SETVAR PrincipalServer SQLHAVPC\SQLDev01 --:SETVAR PrincipalDNS SQLHAVPC --:SETVAR PrincipalPort 5091 -- --:SETVAR MirrorServer SQLHAVPC\SQLDev02 --:SETVAR MirrorDNS SQLHAVPC --:SETVAR MirrorPort 5092 -- --:SETVAR WitnessServer SQLHAVPC\SQLExpress --:SETVAR WitnessDNS SQLHAVPC --:SETVAR WitnessPort 5090 -- --:SETVAR Database2Mirror TicketSalesDB --:SETVAR RestoreWithMove TRUE --:SETVAR BackupLocation "C:\AlwaysOn Labs\Database Mirroring Lab" --go :ON ERROR EXIT go :CONNECT $(PrincipalServer) -- Mirroring ONLY supports the FULL Recovery Model ALTER DATABASE $(Database2Mirror) SET RECOVERY FULL go CREATE ENDPOINT Mirroring STATE=STARTED AS TCP (LISTENER_PORT=$(PrincipalPort)) FOR DATABASE_MIRRORING (ROLE=ALL) GO :CONNECT $(MirrorServer) CREATE ENDPOINT Mirroring STATE=STARTED AS TCP (LISTENER_PORT=$(MirrorPort)) FOR DATABASE_MIRRORING (ROLE=ALL) GO :CONNECT $(WitnessServer) CREATE ENDPOINT Mirroring STATE=STARTED AS TCP (LISTENER_PORT=$(WitnessPort)) FOR DATABASE_MIRRORING (ROLE=WITNESS) GO :CONNECT $(PrincipalServer) BACKUP DATABASE $(Database2Mirror) TO DISK = '$(BackupLocation)\$(Database2Mirror).bak' WITH INIT GO :CONNECT $(MirrorServer) DECLARE @InstanceName sql_variant, @InstanceDir sql_variant, @SQLDataRoot nvarchar(512), @ExecStr nvarchar(max) IF '$(RestoreWithMove)' = 'TRUE' BEGIN SELECT @InstanceName = ISNULL(SERVERPROPERTY('InstanceName'), 'MSSQLServer') EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', 'SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL', @InstanceName, @InstanceDir OUTPUT SELECT @ExecStr = 'EXECUTE master.dbo.xp_regread ' + '''HKEY_LOCAL_MACHINE'', ' + '''SOFTWARE\Microsoft\Microsoft SQL Server\' + convert(varchar, @InstanceDir) + '\Setup'', ''SQLDataRoot'', @SQLDataRoot OUTPUT' EXEC master.dbo.sp_executesql @ExecStr , N'@SQLDataRoot nvarchar(512) OUTPUT' , @SQLDataRoot OUTPUT IF @SQLDataRoot IS NULL BEGIN RAISERROR ('Did not find the correct SQL Data Root Directory. Cannot proceed. Databases backed up but not yet restored.', 16, -1) END CREATE TABLE #BackupFileList ( LogicalName sysname NULL , PhysicalName sysname NULL , [Type] char(1) , FileGroupName sysname NULL , Size bigint , MaxSize bigint , FileId smallint , CreateLSN numeric(25,0) , DropLSN numeric(25,0) , UniqueId uniqueidentifier , ReadOnlyLSN numeric(25,0) , ReadWriteLSN numeric(25,0) , BackupSizeInBytes bigint , SourceBlockSize bigint , FileGroupId smallint , LogGroupGUID uniqueidentifier , DifferentialBaseLSN numeric(25,0) , DifferentialBaseGUID uniqueidentifier , IsReadOnly bit , IsPresent bit ) INSERT #BackupFileList EXEC('RESTORE FILELISTONLY FROM DISK = ''$(BackupLocation)\$(Database2Mirror).bak''') UPDATE #BackupFileList SET PhysicalName = @SQLDataRoot + N'\Data\' + REVERSE(SUBSTRING(REVERSE(PhysicalName) , 1, PATINDEX('%\%', REVERSE(PhysicalName)) -1)) DECLARE @LogicalName sysname , @PhysicalName sysname DECLARE FileListCursor CURSOR FAST_FORWARD FOR SELECT LogicalName, PhysicalName FROM #BackupFileList OPEN FileListCursor FETCH NEXT FROM FileListCursor INTO @LogicalName, @PhysicalName SELECT @ExecStr = N'RESTORE DATABASE $(Database2Mirror)' + N' FROM DISK = ''$(BackupLocation)\$(Database2Mirror).bak'' ' SELECT @ExecStr = @ExecStr + N' WITH MOVE ''' + @LogicalName + N''' TO ''' + @PhysicalName + N'''' FETCH NEXT FROM FileListCursor INTO @LogicalName, @PhysicalName WHILE @@FETCH_STATUS <> -1 BEGIN SELECT @ExecStr = @ExecStr + N', MOVE ''' + @LogicalName + ''' TO ''' + @PhysicalName + '''' FETCH NEXT FROM FileListCursor INTO @LogicalName, @PhysicalName END -- NORECOVERY is required for Database Mirroring, replace is not. -- Replace is used here solely to allow repetitive use of this script. SELECT @ExecStr = @ExecStr + N' , NORECOVERY, REPLACE' DEALLOCATE FileListCursor END ELSE BEGIN -- NORECOVERY is required for Database Mirroring, replace is not. -- Replace is used here solely to allow repetitive use of this script. SELECT @ExecStr = N'RESTORE DATABASE $(Database2Mirror)' + N' FROM DISK = ''$(BackupLocation)\$(Database2Mirror).bak'' ' + N'WITH NORECOVERY, REPLACE' END -- Useful for testing -- Only return the string and then comment out the EXEC line below. -- SELECT @ExecStr EXEC (@ExecStr) GO :CONNECT $(PrincipalServer) -- Backup the transaction log to get these two databases closer to current. BACKUP LOG $(Database2Mirror) TO DISK = '$(BackupLocation)\$(Database2Mirror)_Log.bak' WITH INIT GO :CONNECT $(MirrorServer) -- Restore the transaction log. RESTORE LOG $(Database2Mirror) FROM DISK = '$(BackupLocation)\$(Database2Mirror)_Log.bak' WITH NORECOVERY GO -- Establish the mirroring partnership ALTER DATABASE $(Database2Mirror) SET PARTNER = 'TCP://$(PrincipalDNS):$(PrincipalPort)' GO :CONNECT $(PrincipalServer) ALTER DATABASE $(Database2Mirror) SET PARTNER = 'TCP://$(MirrorDNS):$(MirrorPort)' GO ALTER DATABASE $(Database2Mirror) SET WITNESS = 'TCP://$(WitnessDNS):$(WitnessPort)' GO SELECT db_name(sd.[database_id]) AS [Database Name], sd.mirroring_role_desc, sd.mirroring_partner_name, sd.mirroring_state_desc, sd.mirroring_witness_name, sd.mirroring_witness_state_desc, sd.mirroring_safety_level_desc FROM sys.database_mirroring AS sd WHERE sd.[database_id] = db_id(N'$(Database2Mirror)') GO -------------------------------------------------------------------- -- CLEAN UP SECTION -------------------------------------------------------------------- -- -- BEGIN CLEANUP... -- --Copy your variables here... --GO -- --:CONNECT $(PRINCIPALSERVER) -- --USE MASTER --GO -- --SELECT * FROM SYS.DATABASE_MIRRORING_ENDPOINTS --SELECT * FROM SYS.ENDPOINTS --SELECT * FROM SYS.TCP_ENDPOINTS --GO -- --ALTER DATABASE $(DATABASE2MIRROR) -- SET PARTNER OFF --GO -- --DROP ENDPOINT MIRRORING --GO -- ----DROP DATABASE $(DATABASE2MIRROR) ----GO -- --:CONNECT $(MIRRORSERVER) -- --DROP ENDPOINT MIRRORING --GO -- --ALTER DATABASE $(DATABASE2MIRROR) -- SET PARTNER OFF --GO --DROP DATABASE $(DATABASE2MIRROR) --GO -- --:CONNECT $(WITNESSSERVER) -- --DROP ENDPOINT MIRRORING --GO -- ---- TO RESTORE ADVENTUREWORKS BACK TO THE ORIGINAL VERSION, ---- PLEASE REFER TO THIS SECTION OF THE BOOKS ONLINE: ---- MS-HELP://MS.SQLCC.V9/MS.SQLSVR.V9.EN/INSTSQL9/HTML/7DE6CEB0-BE7A-4309-894B-A0963DC6C27B.HTM -- ------ END CLEANUP...