天天看點

腳本分享:别人家的鏡像自動化部署

腳本分享:别人家的鏡像自動化部署

腳本1:

執行個體名:

主伺服器:X

鏡像伺服器:Y

步驟:

1. 在主伺服器和鏡像伺服器之間建立連結伺服器,配置為使用RPC(Remote procedure call)調用,為了執行SP。

例如:lnk_X_Y_mirroring(連結伺服器名)

2. 在主伺服器上建立以下SP。

3. 根據需要使用作業每30分鐘或1小時調用SP(usp_Mirroring_Configuration)。

4. 一旦一個新資料庫建立,鏡像會通過作業的執行被部署。

5. 将觸發“Mirroring Configuration”為名的告警,内容為“Mirroring Configured for db_55555 and safety level is OFF”

/*******************************************************************************
DESCRIPTION: Automatic Mirroring_Configuration for new databases
AUTHOR: Vasan
DATE WRITTEN: 17 MARCH 2015
Automatic Mirroring configuration for newly created user databases:
-------------------------------------------------------------------
Instance names:
---------------
Principle server : X
Mirroring Server : Y
Steps to follow:
1. Create link server between principle server and mirror server with RPC (Remote procedure call) set as true in order to execute the procedure.
Eg : lnk_X_Y_mirroring (Link server name)
2. Create below stored procedure in to principle server.
3. Schedule this Stored procedure (usp_Mirroring_Configuration) with 30mins/1hr interval via job
4. Once the new database created in server mirroring will be configure.
5. Alert will be trigger with the subject anme of Mirroring Configuration
Mail contect:“Mirroring Configured for db_55555 and safety level is OFF”
*******************************************************************************/
Begin
SET NOCOUNT ON;
IF OBJECT_ID(N'tempdb..##tbl_new_databases') IS NOT NULL
BEGIN
DROP TABLE ##tbl_new_databases
END
Declare @dbname nvarchar(max)
Declare @Path nvarchar(500)
Declare @todiskbkp nvarchar(max)
Declare @todisklogbkp nvarchar(max)
Declare @SQL nvarchar(max)
Declare @count SMALLINT
Declare @SQLpartnerprimary nvarchar(max)
Declare @SQLmirror nvarchar(max)
Declare @Mirrorsaftey nvarchar(max)
-- Restore Part Variables
Declare @RestorePath nvarchar(500)
Declare @fromdiskbkp nvarchar(max)
Declare @fromdisklogbkp nvarchar(max)
Declare @SQLrestore nvarchar(max)
Declare @SQLpartnermirror nvarchar(max)
--Mail Part
DECLARE @tableHTML NVARCHAR(MAX) ;
DECLARE @bodyMsg nvarchar(max)
DECLARE @subject nvarchar(max)
SELECT A.name into ##tbl_new_databases
FROM
sys.databases A INNER JOIN sys.database_mirroring B
ON A.database_id=B.database_id
WHERE a.database_id > 4 and B.mirroring_state is NULL and A.is_read_only=0 and state_desc='ONLINE'
if (Select COUNT(*) from ##tbl_new_databases)>0
Begin
DECLARE DB CURSOR FOR
-- Fetching newly created database to configure mirroring
Select name from ##tbl_new_databases
OPEN DB
FETCH NEXT FROM DB INTO @dbname
WHILE @@FETCH_STATUS=0
BEGIN
-- changing recovery model from Simple to Full for new database since new database created with simple recovery model
set @sql= 'if (SELECT recovery_model_desc FROM sys.databases where name = '''+@dbname+''' ) = ''SIMPLE''
begin
Use master
ALTER DATABASE '+@dbname+' SET RECOVERY FULL WITH NO_WAIT
end'
--print @sql
EXEC master.dbo.sp_executesql @SQL
-- Setting Backup folder path for primary server
--(Backup should be placed some common path or with in mirror server for easy recovery process) here i chose mirror server local drive
Set @dbname=@dbname
Set @Path='\\Mirror Server Name (Y)\d$\backup\'+@dbname
set @todiskbkp=@Path+'\'+@dbname+'_'+ replace(CONVERT(VARCHAR(11),GETDATE(),106),' ','')+'.bak'
set @todisklogbkp=@Path+'\'+@dbname+'_'+ replace(CONVERT(VARCHAR(11),GETDATE(),106),' ','')+'.trn'
-- Creating new backup folder for new db in Mirror server
EXEC master.dbo.xp_create_subdir @Path
--Create Database Backups for new db
set @SQL= '
BACKUP DATABASE ' +@dbname+'
TO DISK = '''+@todiskbkp+'''
WITH FORMAT;
BACKUP LOG ' +@dbname+'
TO DISK ='''+@todisklogbkp+'''
WITH FORMAT;
'
--Print @SQL
EXEC master.dbo.sp_executesql @SQL
--Restoring the new dataabse to Mirror server
-- Setting Restor path for mirror server
Set @RestorePath='D:\backup\'+@dbname
set @fromdiskbkp=@RestorePath+'\'+@dbname+'_'+ replace(CONVERT(VARCHAR(11),GETDATE(),106),' ','')+'.bak'
set @fromdisklogbkp=@RestorePath+'\'+@dbname+'_'+ replace(CONVERT(VARCHAR(11),GETDATE(),106),' ','')+'.trn'
--Create the Mirror Database (restoring the new database backup into mirror server)
set @SQLrestore='
RESTORE DATABASE '+@dbname+' FROM DISK = N'''+@fromdiskbkp+''' WITH FILE = 1,
MOVE N'''+@dbname+''' TO N''D:\data\'+@dbname+'.mdf'',
MOVE N'''+@dbname+'_log'' TO N''D:\log\'+@dbname+'.LDF'',
NORECOVERY, NOUNLOAD, REPLACE, STATS = 10
RESTORE LOG '+@dbname+' FROM DISK = N'''+@fromdisklogbkp+'''
WITH FILE = 1, NORECOVERY, NOUNLOAD, STATS = 10
'
--print @SQLrestore
EXEC lnk_X_Y_mirroring.master.dbo.sp_executesql @SQLrestore
--Listener Port on mirror server
set @SQLpartnermirror= '
ALTER DATABASE '+@dbname+'
SET PARTNER=''tcp://Domain Name:Port Number'';
'
--print @SQLpartnermirror
EXEC lnk_X_Y_mirroring.master.dbo.sp_executesql @SQLpartnermirror
--Listener Port on principal server
set @SQLpartnerprimary='
ALTER DATABASE '+@dbname+'
SET PARTNER=''tcp://Domain Name:Port Number'';'
EXEC master.dbo.sp_executesql @SQLpartnerprimary
--Print @SQLpartnerprimary
--Set Mirroring Operating Mode to “High Performance”
set @Mirrorsaftey='
ALTER DATABASE '+@dbname+' SET SAFETY OFF
'
--print @SQLpartnermirror
EXEC master.dbo.sp_executesql @Mirrorsaftey
FETCH NEXT FROM DB INTO @DBNAME
END
CLOSE DB
DEALLOCATE DB
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'DBAProfile',
@recipients = '[email protected]',
@subject = 'Mirroring Configuration',
@query='set nocount on SELECT ''Mirroring Configured for ''+ A.name +'' and safety level is ''+ B.[mirroring_safety_level_desc] COLLATE Latin1_General_CI_AI
FROM
sys.databases A
INNER JOIN sys.database_mirroring B
ON A.database_id=B.database_id
WHERE a.database_id > 4 AND A.name in (Select name from ##tbl_new_databases)',
@query_result_no_padding =0,
@query_result_width = 32767,
@query_no_truncate = 1,
@attach_query_result_as_file = 0,
@Body_format = 'text' ,
@append_query_error = 1
Drop table ##tbl_new_databases
END
END      

腳本2:

準備步驟:

1. 安裝和一個輔助SQL Server執行個體(版本、更新檔和LICENSE類型跟主伺服器執行個體一樣)。

2. SQL Server連接配接啟用TCP/IP協定。

3. 為備份和恢複操作配置網絡共享,類似\\dfsroot\sqlbackup

4. 允許使用xp_cmdshell擴充存儲過程。

僅通過一個觸發器通路執行所有的操作是不行的。這個方法包含四個元件:1個事件接收器表,1個工作負載存儲過程,1個DDL觸發器和1個以一定間隔執行之前提到的存儲過程的SQL Server代理作業。

步驟1:建立1個事件接收器表

該表将會儲存CREATE資料庫動作發生時的名字和SQL事件。事件類型不重要,我們隻對資料庫名感興趣。

USE [master]
GO
/****** Object: Table [dbo].[new_db_table] Script Date: 05/19/2008 15:26:56 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[new_db_table](
[name] [nvarchar](100) NULL,
[event] [nvarchar](100) NULL
) ON [PRIMARY]      

步驟2:建立自動化存儲過程

這是主要的腳本,用于檢查動作表,執行備份初始化。在SQL Server 2005,對于附加資料庫動作是沒有資料庫事件的,即便事實上它是一個CREATE_DATABASE事件。在SQL Server 2008解決了,導緻觸發器對于ATTACH和CREATE動作,在動作表都添加一個條目。

USE [master]
GO
/****** Object: StoredProcedure [dbo].[sp_auto_mirror_config] Script Date: 07/10/2008 10:56:15 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
— ============================================================================
— Author: <Jeff Sani,[email protected]>
— Create date: <4/9/2008>
— Description: <This stored proc automates the configuration of db mirroring>
— Syntax: <exec sp_auto_mirror_config>
— =============================================================================
CREATE proc [dbo].[sp_auto_mirror_config]
as
declare @dbname sysname, @bckstmt nvarchar(500), @cmd varchar(250), @bupath varchar(100)
declare @mirrorsp nvarchar(100), @mirrorsql nvarchar(500), @altersql nvarchar(250)
declare @primarysrvr nvarchar(50), @mirrorsrvr nvarchar(50), @witnesssrvr nvarchar(50), @domain nvarchar(50)
–set your sql server and backup paths here
set @bupath = ‘\\sql1\sqlbackup’
set @primarysrvr = ‘sql1’
set @mirrorsrvr = ‘sql2’
set @domain = ‘.staging.local’
set @witnesssrvr = ‘smres2’
set @mirrorsp = @mirrorsrvr + ‘.master.dbo.sp_executesql ‘
begin
if (select count(*) from new_db_table where event = ‘CREATE_DATABASE’) > 0
begin
create table #userdbs (name sysname)
insert into #userdbs select name from new_db_table
declare cdb cursor for select name from #userdbs
open cdb
fetch cdb into @dbname
while @@fetch_status = 0
begin
–Check to make sure that Auto_Close and Auto_Shrink DB Properties are correct and that Recovery is Full
set @altersql = ‘alter database ‘ + char(91) + @dbname + char(93) + ‘ set AUTO_CLOSE off’
exec (@altersql)
set @altersql = ‘alter database ‘ + char(91) + @dbname + char(93) + ‘ set AUTO_SHRINK on’
exec (@altersql)
set @altersql = ‘alter database ‘ + char(91) + @dbname + char(93) + ‘ set RECOVERY full’
exec (@altersql)
–perform initial database backup
set @bckstmt = ‘backup database ‘ + char(91) + @dbname + char(93)+ ‘ to ‘ +
‘disk = N’ + char(39) + @bupath + ‘\’ + @dbname + ‘.bak’ + char(39)
exec (@bckstmt)
–perform initial database log backup
set @bckstmt = ‘backUp log ‘ + char(91) + @dbname + char(93)+ ‘ to ‘ +
‘disk = N’ + char(39) + @bupath + ‘\’ + @dbname + ‘_log.bak’ + char(39)
exec (@bckstmt)
–perform database restore on linked remote mirror sql server
set @bckstmt = ‘restore database ‘ + char(91) + @dbname + char(93) + ‘ from ‘ +
‘Disk = N’ + char(39) + @bupath + ‘\’ + @dbname + ‘.bak’ + char(39) + ‘ with norecovery, replace’
exec @mirrorsp @bckstmt
–perform database log restore on linked remote mirror sql server
set @bckstmt = ‘restore log ‘ + char(91) + @dbname + char(93) + ‘ from ‘ +
‘Disk = N’ + char(39) + @bupath + ‘\’ + @dbname + ‘_log.bak’ + char(39) + ‘ with norecovery, replace’
exec @mirrorsp @bckstmt
–Initiate the mirroring on The Mirror server:
set @mirrorsql = ‘alter database ‘ + char(91) + @dbname + char(93) + ‘ set partner= N’+ char(39) + ‘TCP://’ + @primarysrvr + @domain + ‘:5022’ + char(39)
exec @mirrorsp @mirrorsql
–Initiate the mirroring on The Primary server:
set @mirrorsql = ‘alter database ‘ + char(91) + @dbname + char(93) + ‘ set partner= N’+ char(39) + ‘TCP://’ + @mirrorsrvr + @domain + ‘:5022’ + char(39)
exec (@mirrorsql)
–Enable the mirroring session on the Witness server:
set @mirrorsql = ‘alter database ‘ + char(91) + @dbname + char(93) + ‘ set witness= N’+ char(39) + ‘TCP://’ + @witnesssrvr + @domain + ‘:5022’ + char(39)
exec (@mirrorsql)
–cleanup
delete from new_db_table where name = @dbname
set @cmd = ‘del ‘ + @bupath + ‘\’ + @dbname + ‘.bak’
exec xp_cmdshell @cmd
set @cmd = ‘del ‘ + @bupath + ‘\’ + @dbname + ‘_log.bak’
exec xp_cmdshell @cmd
fetch cdb into @dbname
end
close cdb
deallocate cdb
drop table #userdbs
end
end      

步驟3:建立觸發器

當比對CREATE_DATABASE的事件發生時,它将觸發,将資料庫名寫入事件接收器表。

/****** Object: DdlTrigger [trg_MirrorDDL] Script Date: 05/19/2008 15:31:55 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [trg_MirrorDDL]
ON ALL SERVER
FOR CREATE_DATABASE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @data XML;
DECLARE @eventType sysname;
DECLARE @dbname varchar(100);
DECLARE @mirrorsql varchar(500);
SET @data = EVENTDATA();
SET @eventType = @data.value(‘(/EVENT_INSTANCE/EventType)[1]’, ‘sysname’);
SET @dbname = @data.value(‘(/EVENT_INSTANCE/ DatabaseName)[1]’, ‘sysname’);
–Add to new_db_table
Insert new_db_table(name,event) select @dbname,@eventType where not exists (select * from new_db_table where name = @dbname);
END
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
ENABLE TRIGGER [trg_MirrorDDL] ON ALL SERVER      

步驟4:建立SQL Server代理作業

這個作業主要的目的是監控事件接收器表的新增條目。我原本想在事件接收器表上用一個觸發器,但是你可能不想自動化,而是想通過作業來按需排程存儲過程的執行可能會更好。

USE [msdb]
GO
/****** Object: Job [Mirroring Agent] Script Date: 05/19/2008 15:32:54 ******/
BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
/****** Object: JobCategory [[Uncategorized (Local)]]] Script Date: 05/19/2008 15:32:54 ******/
IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]’ AND category_class=1)
BEGIN
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N’JOB’, @type=N’LOCAL’, @name=N'[Uncategorized (Local)]’
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
END
DECLARE @jobId BINARY(16)
EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N’Mirroring Agent’,
@enabled=1,
@notify_level_eventlog=2,
@notify_level_email=0,
@notify_level_netsend=0,
@notify_level_page=0,
@delete_level=0,
@description=N’No description available.’,
@category_name=N'[Uncategorized (Local)]’,
@owner_login_name=N’SMNET\administrator’, @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** Object: Step [Run Mirroring Stored Procedure] Script Date: 05/19/2008 15:32:55 ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N’Run Mirroring Stored Procedure’,
@step_id=1,
@cmdexec_success_code=0,
@on_success_action=1,
@on_success_step_id=0,
@on_fail_action=2,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N’TSQL’,
@command=N’USE [master]
GO
DECLARE @return_value int
EXEC @return_value = [dbo].[sp_auto_mirror_config]
SELECT ”Return Value” = @return_value
GO’,
@database_name=N’master’,
@flags=4
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N’Mirror Agent Schedule’,
@enabled=1,
@freq_type=4,
@freq_interval=1,
@freq_subday_type=4,
@freq_subday_interval=5,
@freq_relative_interval=0,
@freq_recurrence_factor=0,
@active_start_date=20080410,
@active_end_date=99991231,
@active_start_time=0,
@active_end_time=235959
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)’
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:      

後記:

這兩個腳本都是将資料直接備份到遠端UNC路徑。筆者之前在Bash下寫過鏡像自動化部署,日志傳送自動化部署、檢查和切換的腳本,資料傳輸用的winscp.exe,思路也就是把這些核心SQL封裝調用。

參考:

繼續閱讀