1. 程式人生 > >sql server自動化運維指令碼

sql server自動化運維指令碼

資料庫運維中盛傳一個小段子,我誤刪除了資料庫,改怎麼辦?有備份還原備份,沒有備份就準備簡歷!聽起來有趣但發生在誰身上,誰都笑不起來。接觸了很多的客戶發現90%客戶的運維策略都不是很完善。本篇就分享一些常規的運維指令碼,本篇沒有涉及到的或不足的也請大家留言無私貢獻深藏多年的指令碼,謝謝!

郵件

  郵件主要用來監控作業是否執行成功,如果您已經配置了類似zabbix等軟體請忽略。

配置郵件服務

  

複製程式碼 複製程式碼
--SQL Server 並沒有內建郵件伺服器(Mail Server),它跟我們傳送郵件一樣,需要使用者名稱和密碼通過 SMTP(Simple Message Transfer Protocol)去連線郵件伺服器。我們想讓 SQL Server 來發送郵件,首先要告訴它使用者名稱稱,密碼,伺服器地址,網路傳送協議,郵件伺服器的埠。。。等資訊。
--  以下指令碼實現了資料庫郵件的配置:
----下面是具體的配置郵件步驟 
----在 sa 系統帳戶下執行。 
--
--1. 啟用 SQL Server  郵件功能。 
use master
go
exec sp_configure 'show advanced options',1 
go 
reconfigure with override
go
exec sp_configure 'Database Mail XPs',1
go
reconfigure  with override
go
--2. 在 SQL Server  中新增郵件帳戶(account) 
exec msdb..sysmail_add_account_sp
        @account_name            = '163yx'      -- 郵件帳戶名稱(SQL Server 使用)
       ,@email_address           = '
[email protected]
' -- 發件人郵件地址 ,@display_name = null -- 發件人姓名 ,@replyto_address = null ,@description = null ,@mailserver_name = 'smtp.163.com' -- 郵件伺服器地址 ,@mailserver_type = 'SMTP' -- 郵件協議(SQL 2005 只支援 SMTP) ,@port = 25 -- 郵件伺服器埠 ,@username = '
[email protected]
' -- 使用者名稱 ,@password = 'XXXXX' -- 密碼 ,@use_default_credentials = 0 ,@enable_ssl = 0 ,@account_id = null --3. 在 SQL Server 中新增 profile exec msdb..sysmail_add_profile_sp @profile_name = 'dba_profile3' -- profile 名稱 ,@description = 'dba mail profile' -- profile 描述 ,@profile_id = null -- 在 SQL Server 中對映 account 和 profile exec msdb..sysmail_add_profileaccount_sp @profile_name = 'dba_profile3' -- profile 名稱 ,@account_name = '163yx' -- account 名稱 ,@sequence_number = 1 -- account 在 profile 中順序 --5. 利用 SQL Server Database Mail 功能傳送郵件。 exec msdb..sp_send_dbmail @profile_name = 'dba_profile3' -- profile 名稱 ,@recipients = '
[email protected]
;[email protected]' -- 收件人郵箱 ,@subject = 'SQL Server Mail 測試' -- 郵件標題 ,@body = 'Hello Mail!測試' -- 郵件內容 ,@body_format = 'TEXT' -- 郵件格式 ,@file_attachments = 'c:\a.txt' --郵件附件 --6. 檢視郵件傳送情況: use msdb go select * from sysmail_allitems select * from sysmail_mailitems select * from sysmail_event_log --如果不是以 sa 帳戶傳送郵件,則可能會出現錯誤: -- --Msg 229, Level 14, State 5, Procedure sp_send_dbmail, Line 1 --EXECUTE permission denied on object 'sp_send_dbmail', database 'msdb', schema 'dbo'. -- --這是因為,當前 SQL Server 登陸帳戶(login),在 msdb 資料庫中沒有傳送資料庫郵件的許可權,需要加入 msdb 資料庫使用者,並通過加入 sp_addrolemember 角色賦予許可權。假設該SQL Server 登陸帳戶名字為 “dba” -- --use msdb --go -- --create user dba for login dba --go -- --exec dbo.sp_addrolemember @rolename = 'DatabaseMailUserRole', -- @membername = 'dba' --go -- --此時,再次傳送資料庫郵件,仍可能有錯誤: -- --Msg 14607, Level 16, State 1, Procedure sp_send_dbmail, Line 119 --profile name is not valid -- --雖然,資料庫使用者 “dba” 已經在 msdb 中擁有傳送郵件的許可權了,但這還不夠,他還需要有使用 profile:“dba_profile” 的許可權。 -- --use msdb --go -- --exec sysmail_add_principalprofile_sp @principal_name = 'dba' -- ,@profile_name = 'dba_profile' -- ,@is_default = 1 -- --從上面的引數 @is_default=1 可以看出,一個數據庫使用者可以在多個 mail profile 擁有傳送許可權。 --EXEC msdb.dbo.sysmail_configure_sp 'MaxFileSize', 100000000 (位元組)設定郵件.note
複製程式碼 複製程式碼

 

 

配置操作員

  操作員主要是用於作業的通知物件:

  

  

  配置如下:

  

  

複製程式碼 複製程式碼
USE [msdb]
GO
EXEC msdb.dbo.sp_add_operator @name=N'mail_user2', 
        @enabled=1, 
        @pager_days=0, 
        @email_address=N'KK_XXXX.163.COM'
GO
複製程式碼 複製程式碼

 

 

  注 :操作員可根據是否在作業成功或失敗時通知,後續指令碼均未配置操作員,如需配置可在作業屬性中自行新增 

  

 

AlwaysOn相關

節點切換監控

  

複製程式碼 複製程式碼
    declare @role VARCHAR(8000);    
    declare @email_conetent varchar(8000);--存放郵件正文 
    declare @name varchar(100);
    declare @lastsend int;
declare @subject_str varchar(100);
    set @name =(select @@servername)
set @subject_str = @name + 'always on 預警'
    set @role=(SELECT role FROM sys.dm_hadr_availability_replica_states WHERE is_local=1)
    set @lastsend = (select isnull(datediff(MINUTE,max(send_request_date), getdate()),6000) from [msdb].[dbo].[sysmail_mailitems] where subject = @subject_str)

     if @role >1 and @lastsend > 30  ----30分鐘傳送一次
        begin 
            set  @email_conetent=(@name+'當前節點不是主節點,發生故障轉移')
            print(@email_conetent)
print(@lastsend)
--if @lastsend > 1
            --傳送郵件  
                      --郵件正文內容
            EXEC msdb.dbo.sp_send_dbmail 
                @profile_name = 'DB-mail',         --配置檔名稱
                @recipients = '[email protected]',  --收件email地址
                @subject = @subject_str,                 --郵件主題
                @body = @email_conetent    
        end 
複製程式碼 複製程式碼

 

 

 

節點切換作業控制

  作業可以採用手動控制或如下指令碼,也可以修改作業在作業執行前增加節點判斷

複製程式碼 複製程式碼
--------------------------判斷當前節點是否為主節點 如果不是則禁用作業 -------
------------節點 切換為主節點則啟用JOB ------------
DECLARE @ROLE tinyint 
DECLARE @ENABLE tinyint 
----判斷是否是主節點 --1 主節點
 SELECT @role=role FROM sys.dm_hadr_availability_replica_states WHERE is_local=1

--判斷JOB狀態  --0 禁用 1 啟用
--以syspolicy_purge_history 為 參照 --如果 禁用或刪除syspolicy_purge_history請修改 @ENABLE下段查詢
SELECT @ENABLE  = [ENABLED] 
FROM MSDB.[dbo].[sysjobs] 
WHERE NAME = 'syspolicy_purge_history'


-----第一次切換 輔助節點沒有建立CDC作業 job 則建立作業 [category_id] = 13 CDC LOG SCAN JOB
if not exists (select 1 from msdb.dbo.sysjobs where [category_id]= 13 or [category_id]= 16 ) and  @ROLE = 1
begin 
EXEC sys.sp_cdc_add_job @job_type = 'capture';
EXEC sys.sp_cdc_add_job @job_type = 'cleanup';
end

---primary and job disable set job enable
IF @ROLE = 1 and @ENABLE = 0
BEGIN

----如果存在原有作業為禁用,無法確定哪些JOB需要開啟....所以此處最好手動維護作業的啟用和禁用
EXEC msdb.dbo.sp_update_job
    @job_name = N'XXXXX',
    @enabled = 1 ;


-----執行 CDC 
EXEC msdb.dbo.sp_start_job @job_name = N'cdc.XX_capture'
EXEC msdb.dbo.sp_start_job @job_name = N'cdc.XX_cleanup'
end
---not primary and job enable set  disable
IF @ROLE <> 1 and @ENABLE  = 1
BEGIN
----如果存在原有作業為禁用,無法確定哪些JOB需要開啟....所以此處最好手動維護作業的啟用和禁用
EXEC msdb.dbo.sp_update_job
    @job_name = N'XXXXX',
    @enabled = 0 ;

END
複製程式碼 複製程式碼

 

資料備份

  備份方案:每天全備份、6小時一次差異備份、一小時一次日誌備份。

備份儲存過程

  儲存過程建立後會保留在master庫中,儲存過程主要控制備份邏輯,備份路徑等。

  儲存過程中只有一個型別引數,用於控制全備/差異/日誌備份,可根據需要修改。

複製程式碼 複製程式碼
USE [master]
GO

/****** Object:  StoredProcedure [dbo].[sp_BackupDatabase]    Script Date: 01/22/2015 13:52:46 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

-- Author: KK

-- Create date: 2016-09-27

-- Description: 備份資料庫,備份路徑F:\KK_BackUp\ 可自行修改

-- http://www.cnblogs.com/double-K/

-- Parameter1: 備份型別 F=全部, D=差異, L=日誌

alter PROCEDURE [dbo].[sp_BackupDatabase]
@backupType CHAR(1)
AS
BEGIN
SET NOCOUNT ON;



declare @filepath_backup varchar(100)
declare @dateTime varchar(30),@del_time_stamp varchar(50)
DECLARE @sqlCommand NVARCHAR(1000)

---建立資料庫對應資料夾
EXECUTE master.dbo.xp_create_subdir N'F:\KK_BackUp\Full\'
EXECUTE master.dbo.xp_create_subdir N'F:\KK_BackUp\Difference\'
EXECUTE master.dbo.xp_create_subdir N'F:\KK_BackUp\Log_Bak\'

IF @backupType = 'F'
set @filepath_backup='F:\KK_BackUp\Full\'
IF @backupType = 'D'
set @filepath_backup='F:\KK_BackUp\Difference\'
IF @backupType = 'L'
set @filepath_backup='F:\KK_BackUp\Log_Bak\'

SET ANSI_WARNINGS OFF
SET @dateTime = replace(convert(varchar,current_timestamp, 112)+'_'+convert(varchar,current_timestamp, 108),':','')

----刪除超過3天的備份檔案
DECLARE @delete_time datetime
set @delete_time = getdate() - 3

EXECUTE master.dbo.xp_delete_file 0,N'F:\kk_backup',N'trn',@delete_time,1
EXECUTE master.dbo.xp_delete_file 0,N'F:\kk_backup',N'bak',@delete_time,1

SELECT @dateTime = replace(convert(varchar,current_timestamp, 112)+'_'+convert(varchar,current_timestamp, 108),':','')





declare db_info cursor for    
SELECT NAME,recovery_model FROM MASTER.SYS.databases 
where state = 0 ---只處理online的資料庫 
and name not in ('tempdb','ReportServerTempDB','ReportServer')  ----填寫不需要備份的資料庫


declare @databaseName nvarchar(128) 
declare @recovery_model  int
OPEN db_info    
fetch next from db_info into @databaseName,@recovery_model 
while @@fetch_status=0    
Begin    

---recovery_model 1 : FULL 2 : BULK_LOGGED 3:SIMPLE
---系統資料庫只全備

IF @backupType = 'F' 

SET @sqlCommand = 'BACKUP DATABASE '+ @databaseName +' TO DISK = '''+ @filepath_backup + ''+ @databaseName +'_Full_'[email protected]+'.BAK'' with STATS = 10, INIT, COMPRESSION, CHECKSUM '

IF @backupType = 'D' and @databaseName not in ('master','msdb','model')

SET @sqlCommand = 'BACKUP DATABASE '+ @databaseName +' TO DISK = '''+ @filepath_backup + ''+ @databaseName + '_Diff_' + @dateTime + '.BAK '' WITH DIFFERENTIAL, STATS = 10, INIT, COMPRESSION'

IF @backupType = 'L' and @recovery_model <> 3 and @databaseName not in ('master','msdb','model')
SET @sqlCommand = 'BACKUP LOG '+ @databaseName +' TO DISK = '''+ @filepath_backup + '' + @databaseName +'_Log_' + @dateTime + '.TRN'' with STATS = 10, INIT, COMPRESSION'
print @sqlCommand



EXECUTE sp_executesql @sqlCommand 


fetch next from db_info into @databaseName,@recovery_model 
End    

close db_info    
deallocate db_info    

PRINT '-- Backup completed successfully at '+convert(varchar, getdate(), 120)    

SET ANSI_WARNINGS ON
END
GO
複製程式碼 複製程式碼

 

備份作業

  備份作業很簡單,就是呼叫儲存過程用計劃控制備份頻率

  

複製程式碼 複製程式碼
-- Author: KK

-- Create date: 2016-09-27

-- Description: 備份資料庫,全備份每天一次 0點執行,差異備份6小時一次,日誌備份1小時一次

-- http://www.cnblogs.com/double-K/

--需要備份的資料庫未使用引數傳遞,而是選擇在儲存過程中指定,當新增新庫時不需要修改任何指令碼

-- Parameter1: 備份型別 F=全部, D=差異, L=日誌


-------------------完整備份作業-----------------
USE [msdb]
GO

/****** Object:  Job [FULL_BACKUP]    Script Date: 2016/9/30 12:13:12 ******/
BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
/****** Object:  JobCategory [[Uncategorized (Local)]]]    Script Date: 2016/9/30 12:13:12 ******/
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'FULL_BACKUP', 
        @enabled=1, 
        @notify_level_eventlog=0, 
        @notify_level_email=0, 
        @notify_level_netsend=0, 
        @notify_level_page=0, 
        @delete_level=0, 
        @description=N'系統全備份', 
        @category_name=N'[Uncategorized (Local)]', 
        @owner_login_name=N'sa', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** Object:  Step [FULL_STEP1]    Script Date: 2016/9/30 12:13:12 ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @[email protected], @step_name=N'FULL_STEP1', 
        @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'[dbo].[sp_BackupDatabase] ''F''', 
        @database_name=N'master', 
        @flags=0
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 @[email protected], @name=N'EVERY_1d_zero', 
        @enabled=1, 
        @freq_type=4, 
        @freq_interval=1, 
        @freq_subday_type=1, 
        @freq_subday_interval=0, 
        @freq_relative_interval=0, 
        @freq_recurrence_factor=0, 
        @active_start_date=20160930, 
        @active_end_date=99991231, 
        @active_start_time=0, 
        @active_end_time=235959, 
        @schedule_uid=N'813653e1-4128-4f47-b378-5a26b49085d0'
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:

GO





-------------------日誌備份作業------------------
USE [msdb]
GO

/****** Object:  Job [LOG_BACKUP]    Script Date: 2016/9/30 12:13:25 ******/
BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
/****** Object:  JobCategory [[Uncategorized (Local)]]]    Script Date: 2016/9/30 12:13:25 ******/
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'LOG_BACKUP', 
        @enabled=1, 
        @notify_level_eventlog=0, 
        @notify_level_email=0, 
        @notify_level_netsend=0, 
        @notify_level_page=0, 
        @delete_level=0, 
        @description=N'系統日誌備份', 
        @category_name=N'[Uncategorized (Local)]', 
        @owner_login_name=N'sa', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** Object:  Step [LOG_STEP1]    Script Date: 2016/9/30 12:13:25 ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @[email protected], @step_name=N'LOG_STEP1', 
        @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'[dbo].[sp_BackupDatabase] ''L''', 
        @database_name=N'master', 
        @flags=0
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 @[email protected], @name=N'EVERY_1h', 
        @enabled=1, 
        @freq_type=4, 
        @freq_interval=1, 
        @freq_subday_type=8, 
        @freq_subday_interval=1, 
        @freq_relative_interval=0, 
        @freq_recurrence_factor=0, 
        @active_start_date=20160930, 
        @active_end_date=99991231, 
        @active_start_time=0, 
        @active_end_time=235959, 
        @schedule_uid=N'3d5ad87e-4f1d-46ef-9a24-e0f99c7d5c20'
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:

GO



----------------------差異備份作業
USE [msdb]
GO

/****** Object:  Job [DIFF_BACKUP]    Script Date: 2016/9/30 12:13:19 ******/
BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
/****** Object:  JobCategory [[Uncategorized (Local)]]]    Script Date: 2016/9/30 12:13:19 ******/
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'DIFF_BACKUP', 
        @enabled=1, 
        @notify_level_eventlog=0, 
        @notify_level_email=0, 
        @notify_level_netsend=0, 
        @notify_level_page=0, 
        @delete_level=0, 
        @description=N'無描述。', 
        @category_name=N'[Uncategorized (Local)]', 
        @owner_login_name=N'sa', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** Object:  Step [DIFF_STEP1]    Script Date: 2016/9/30 12:13:19 ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @[email protected], @step_name=N'DIFF_STEP1', 
        @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'[dbo].[sp_BackupDatabase] ''D''', 
        @database_name=N'master', 
        @flags=0
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 @[email protected], @name=N'EXERY_6h', 
        @enabled=1, 
        @freq_type=4, 
        @freq_interval=1, 
        @freq_subday_type=8, 
        @freq_subday_interval=6, 
        @freq_relative_interval=0, 
        @freq_recurrence_factor=0, 
        @active_start_date=20160930, 
        @active_end_date=99991231, 
        @active_start_time=0, 
        @active_end_time=235959, 
        @schedule_uid=N'f7514c1b-128f-4ae4-8361-9dbcbbff66c6'
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:

GO
複製程式碼 複製程式碼

 

資料一致性檢查

 

複製程式碼 複製程式碼
-- Author: KK

-- Create date: 2016-09-27

-- Description: 資料庫一致性檢查,每週執行及時發現數據庫損壞

-- 本指令碼針對於中小型資料庫,當資料庫達到一定規模超過T級或有大表使用計算列等,可適當拆分或調整,以免checkdb時間超過維護時間視窗而影響業務 -- E:\checkdb_report.txt , 輸出檔案的路徑,檢查出的錯誤資訊或被記錄進去,或直接通過作業記錄檢視 -- http://www.cnblogs.com/double-K/ --需要備份的資料庫未使用引數傳遞,而是選擇在儲存過程中指定,當新增新庫時不需要修改任何指令碼 --指令碼針對中小資料庫,如果資料庫超過1T甚至更大,CHECKDB也是必要操作,但需要拆分檔案組或更精細化檢查以降低每次檢查的時間,保證在指定的維護視窗完成任務。 USE [msdb] GO /****** Object: Job [CHECKDB] Script Date: 09/30/2016 15:16:01 ******/ BEGIN TRANSACTION DECLARE @ReturnCode INT SELECT @ReturnCode = 0 /****** Object: JobCategory [[Uncategorized (Local)]]] Script Date: 09/30/2016 15:16:01 ******/ 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'CHECKDB', @enabled=1, @notify_level_eventlog=0, @notify_level_email=0, @notify_level_netsend=0, @notify_level_page=0, @delete_level=0, @description=N'資料庫一致性檢查,可以發現數據庫是否有損壞。', @category_name=N'[Uncategorized (Local)]', @owner_login_name=N'sa', @job_id = @jobId OUTPUT IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback /****** Object: Step [CHECKDB] Script Date: 09/30/2016 15:16:01 ******/ EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @[email protected], @step_name=N'CHECKDB', @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' declare db_info cursor for SELECT NAME FROM MASTER.SYS.databases where state = 0 ---只處理online的資料庫 and name not in (''tempdb'',''ReportServerTempDB'',''ReportServer'') ----填寫不需要檢查的資料庫 declare @databaseName nvarchar(128) declare @recovery_model int DECLARE @sqlCommand NVARCHAR(1000) OPEN db_info fetch next from db_info into @databaseName while @@fetch_status=0 Begin SET @sqlCommand = ''DBCC CHECKDB(N''''''+ @databaseName + '''''') WITH NO_INFOMSGS'' print @sqlCommand EXECUTE sp_executesql @sqlCommand fetch next from db_info into @databaseName End close db_info deallocate db_info ', @database_name=N'master', @output_file_name=N'E:\checkdb_report.txt', --輸出檔案的路徑,檢查出的錯誤資訊或被記錄進去,或直接通過作業記錄檢視 @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 @[email protected], @name=N'sunday_2am', @enabled=1, @freq_type=8, @freq_interval=1, @freq_subday_type=1, @freq_subday_interval=0, @freq_relative_interval=0, @freq_recurrence_factor=1, @active_start_date=20160930, @active_end_date=99991231, @active_start_time=20000, @active_end_time=235959, @schedule_uid=N'3ade533f-5ce1-434f-98ff-b4509b2ca582' 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: GO
複製程式碼 複製程式碼

 

Agent作業備份

  備份作業可以通過備份MSDB完成,但是保留一份指令碼還是不錯的,指令碼為儲存過程,建議一個周或一個月備份一次,可使用JOB 呼叫儲存過程。

  

複製程式碼 複製程式碼
USE [master]
GO

/****** Object:  StoredProcedure [dbo].[DumpJobsql]    Script Date: 02/07/2014 11:38:46 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

alter PROCEDURE [dbo].[usp_DumpJobsql]
AS
BEGIN


-- Author: KK

-- Create date: 2016-09-27

-- Description: 備份JOB,目前不支援郵件

-- 生成資料一份保留在master的zzz_temp_JOB_bcp表中,另外會在目標位置生成一個 job_日期.sql

-- http://www.cnblogs.com/double-K/






    SET NOCOUNT ON
    DECLARE @SV nvarchar(4)
    DECLARE @i_enabled  TINYINT
    DECLARE @sql VARCHAR(max)
    DECLARE @i_job_name                    VARCHAR(1000)
    DECLARE @i_notify_level_eventlog    INT
    DECLARE @i_notify_level_email        INT
    DECLARE @i_notify_level_netsend        INT
    DECLARE @i_notify_level_page        INT
    DECLARE @i_delete_level                INT
    DECLARE @i_description                VARCHAR(1000)
    DECLARE @i_category_name            VARCHAR(1000)
    DECLARE @i_owner_login_name            VARCHAR(1000)
    DECLARE @i_category_class            INT

    DECLARE @i_start_step_id              INT                                
    DECLARE @i_step_name                 VARCHAR(1000)      
    DECLARE @i_step_id                     INT                
    DECLARE @i_cmdexec_success_code        INT             
    DECLARE @i_on_success_action         INT                
    DECLARE @i_on_success_step_id         INT                
    DECLARE @i_on_fail_action             INT                
    DECLARE @i_on_fail_step_id             INT                
    DECLARE @i_retry_attempts             BIGINT            
    DECLARE @i_retry_interval             INT                
    DECLARE @i_os_run_priority            INT                
    DECLARE @i_subsystem                 VARCHAR(1000)      
    DECLARE @i_command                    VARCHAR(8000)
    DECLARE @i_database_name            VARCHAR(100)              
    DECLARE @i_flags                    INT     

    DECLARE @i_class VARCHAR(10) ,@i_type VARCHAR(10)
    DECLARE @c_jobid UNIQUEIDENTIFIER ,@c_categoryid INT

    DECLARE @loop_stepid                INT
    DECLARE @m_stepid                    INT        
    DECLARE @loop_scheduleid            INT
    DECLARE @m_scheduleid                INT

    DECLARE @i_schedule_enabled            TINYINT
    DECLARE @i_freq_type                INT
    DECLARE @i_schedule_name            VARCHAR(1000)    
    DECLARE @i_freq_interval            INT    
    DECLARE @i_freq_subday_type            INT
    DECLARE @i_freq_subday_interval        INT
    DECLARE @i_freq_relative_interval    INT
    DECLARE @i_freq_recurrence_factor    INT
    DECLARE @i_active_start_date        BIGINT    
    DECLARE @i_active_end_date            BIGINT    
    DECLARE @i_active_start_time        BIGINT    
    DECLARE @i_active_end_time            BIGINT    
    DECLARE @i_schedule_uid                VARCHAR(1000)
    SET @i_class    =    'JOB'
    SET @i_type        =    'LOCAL'

       if exists (select 1 from sys.objects where name = 'zzz_temp_JOB_bcp')
       begin 
          delete from master..zzz_temp_JOB_bcp
       end
       else
       begin 
          create table zzz_temp_JOB_bcp(name nvarchar(100),text nvarchar(max),sv nvarchar(4),Bak_date nvarchar(10))
       end

    DECLARE job CURSOR FOR 
        SELECT a.job_id ,a.category_id,'伺服器XX' as SV 
        FROM msdb.dbo.sysjobs a , msdb.dbo.syscategories c
        WHERE    a.category_id = c.category_id 
                    AND c.name NOT LIKE '%Database Maintenance%' 
                    AND c.name NOT LIKE '%REPL%'
                    AND c.name <> 'Log Shipping'
                    AND a.name <> 'syspolicy_purge_history'
        ----如果需要可多伺服器備份
       --union all
        --select a.job_id ,a.category_id,'伺服器XXX' 
        --from 
        --opendatasource('SQLOLEDB','Data Source=XX.XX.XX.XX;User ID=XX;Password=XX').msdb.dbo.sysjobs a,
        --opendatasource('SQLOLEDB','Data Source=XX.XX.XX.XX;User ID=XX;Password=XX').msdb.dbo.syscategories c
        --WHERE    a.category_id = c.category_id 
        --        AND c.name NOT LIKE '%Database Maintenance%' 
        --        AND c.name NOT LIKE '%REPL%'
        --        AND c.name <> 'Log Shipping'
        --        AND a.name <> 'syspolicy_purge_history'

    OPEN job
    FETCH job INTO @c_jobid ,@c_categoryid,@SV
    WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @sql = ''
        SELECT    @i_job_name                 = a.name ,
                @i_enabled             = [enabled] ,
                @i_notify_level_eventlog = notify_level_eventlog ,
                @i_notify_level_email     = notify_level_email ,
                @i_notify_level_netsend     = notify_level_netsend ,
                @i_notify_level_page     = notify_level_page ,
                @i_delete_level             = delete_level ,
                @i_description             = [description] ,
                @i_category_name         = c.name ,
                @i_owner_login_name         =  ISNULL(SUSER_SNAME(a.owner_sid), N'''') ,
                @i_category_class         = category_class 
                FROM msdb.dbo.sysjobs a ,msdb.dbo.syscategories c
                WHERE a.category_id=c.category_id AND [email protected]_jobid AND a.category_id = @c_categoryid

        SET @[email protected]+CHAR(13)+CHAR(10) + 'USE [msdb]'
        SET @[email protected]+CHAR(13)+CHAR(10) + 'GO'
        SET @[email protected]+CHAR(13)+CHAR(10) + '/****** Object:  Job ['+ @i_job_name +']    Script Date: '+CONVERT(VARCHAR,GETDATE(),22)+' ******/' 
        SET @[email protected]+CHAR(13)+CHAR(10) + 'BEGIN TRANSACTION' 
        SET @[email protected]+CHAR(13)+CHAR(10) + 'DECLARE @ReturnCode INT' 
        SET @[email protected]+CHAR(13)+CHAR(10) + 'SELECT @ReturnCode = 0'
        SET @[email protected]+CHAR(13)+CHAR(10) + '/****** Object:  JobCategory ['+ @i_category_name +']    Script Date: 08/20/2016 12:35:16 ******/'
        SET @[email protected]+CHAR(13)+CHAR(10) + 'IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'''+ @i_category_name +''' AND category_class='+ CAST(@i_category_class AS VARCHAR) +' )' 
        SET @[email protected]+CHAR(13)+CHAR(10) + 'BEGIN' 
        SET @[email protected]+CHAR(13)+CHAR(10) + 'EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'''+ @i_class +''', @type=N'''+ @i_type +''', @name=N'''+ @i_category_name +'''' 
        SET @[email protected]+CHAR(13)+CHAR(10) + 'IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback'
        SET @[email protected]+CHAR(13)+CHAR(10) + '' 
        SET @[email protected]+CHAR(13)+CHAR(10) + 'END'
        SET @[email protected]+CHAR(13)+CHAR(10) + ''
        SET @[email protected]+CHAR(13)+CHAR(10) + 'DECLARE @jobId BINARY(16)' 
        SET @[email protected]+CHAR(13)+CHAR(10) + 'EXEC @ReturnCode =  msdb.dbo.sp_add_job @job_name=N'''+ @i_job_name +''','  
        SET @[email protected]+CHAR(13)+CHAR(10) + '        @enabled='+ CAST(@i_enabled AS VARCHAR) +',' 
        SET @[email protected]+CHAR(13)+CHAR(10) + '        @notify_level_eventlog='+ CAST(@i_notify_level_eventlog AS VARCHAR) +','
        SET @[email protected]+CHAR(13)+CHAR(10) + '        @notify_level_email='+ CAST(@i_notify_level_email AS VARCHAR) +',' 
        SET @[email protected]+CHAR(13)+CHAR(10) + '        @notify_level_netsend='+ CAST(@i_notify_level_netsend AS VARCHAR) +',' 
        SET @[email protected]+CHAR(13)+CHAR(10) + '        @notify_level_page='+ CAST(@i_notify_level_page AS VARCHAR) +',' 
        SET @[email protected]+CHAR(13)+CHAR(10) + '        @delete_level='+ CAST(@i_delete_level AS VARCHAR) +',' 
        SET @[email protected]+CHAR(13)+CHAR(10) + '        @description=N'''+ @i_description +''',' 
        SET @[email protected]+CHAR(13)+CHAR(10) + '        @category_name=N'''+ @i_category_name +''',' 
        SET @[email protected]+CHAR(13)+CHAR(10) + '        @owner_login_name=N'''+ @i_owner_login_name +''', @job_id = @jobId OUTPUT' 
        SET @[email protected]+CHAR(13)+CHAR(10) + 'IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback' 
        IF EXISTS ( SELECT TOP 1 1 FROM msdb.dbo.sysjobsteps WHERE job_id = @c_jobid )
        BEGIN
            SELECT  @loop_stepid = MIN(step_id) ,@m_stepid = MAX(step_id) FROM msdb.dbo.sysjobsteps WHERE job_id = @c_jobid  
            WHILE (@loop_stepid < = @m_stepid) 
            BEGIN     
                SELECT    @i_start_step_id        = start_step_id,
                        @i_step_name            = step_name ,
                        @i_step_id                = step_id,
                        @i_cmdexec_success_code = cmdexec_success_code ,
                        @i_on_success_action    = on_success_action ,
                        @i_on_success_step_id    = on_success_step_id ,
                        @i_on_fail_action        = on_fail_action ,
                        @i_on_fail_step_id        = on_fail_step_id ,
                        @i_retry_attempts        = retry_attempts ,
                        @i_retry_interval        = retry_interval ,
                        @i_os_run_priority        = os_run_priority ,
                        @i_subsystem            = subsystem ,
                        @i_command                = command ,
                        @i_database_name        = database_name ,
                        @i_flags                = flags
                        FROM msdb.dbo.sysjobs a ,msdb.dbo.sysjobsteps b 
                        WHERE a.job_id = b.job_id AND step_id = @loop_stepid AND a.job_id = @c_jobid 

                SET @[email protected]+CHAR(13)+CHAR(10) + '/****** Object:  Step ['+ @i_step_name +']    Script Date: '+CONVERT(VARCHAR,GETDATE(),22)+' ******/' 
                SET @[email protected]+CHAR(13)+CHAR(10) + 'EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @[email protected], @step_name=N'''+ @i_step_name +''','
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @step_id='+ CAST(@i_step_id AS VARCHAR) +',' 
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @cmdexec_success_code='+ CAST(@i_cmdexec_success_code AS VARCHAR) +','  
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @on_success_action='+ CAST(@i_on_success_action AS VARCHAR) +',' 
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @on_success_step_id='+ CAST(@i_on_success_step_id AS VARCHAR) +','  
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @on_fail_action='+ CAST(@i_on_fail_action AS VARCHAR) +','  
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @on_fail_step_id='+ CAST(@i_on_fail_step_id AS VARCHAR) +','  
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @retry_attempts='+ CAST(@i_retry_attempts AS VARCHAR) +','  
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @retry_interval='+ CAST(@i_retry_interval AS VARCHAR) +','  
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @os_run_priority='+ CAST(@i_os_run_priority AS VARCHAR) +', @subsystem=N'''+ @i_subsystem +''','  
                SET @[email protected]+CHAR(13)+CHAR(10) + ISNULL('        @command=N''' + REPLACE(@i_command ,'''' ,'''''') + ''',' ,'')  
                SET @[email protected]+CHAR(13)+CHAR(10) + ISNULL('        @database_name=N'''+ @i_database_name +''',' ,'') 
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @flags='+ CAST(@i_flags AS VARCHAR) 
                SET @[email protected]+CHAR(13)+CHAR(10) + 'IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback' 

                SET @loop_stepid = ( SELECT TOP 1 step_id FROM msdb.dbo.sysjobsteps WHERE job_id = @c_jobid AND step_id > @loop_stepid ORDER BY step_id )
            END
        END

        SET @[email protected]+CHAR(13)+CHAR(10) + 'EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = '+ CAST(@i_start_step_id AS VARCHAR)  
        SET @[email protected]+CHAR(13)+CHAR(10) + 'IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback'  
        IF EXISTS ( SELECT TOP 1 1 FROM msdb.dbo.sysschedules c ,msdb.dbo.sysjobschedules d WHERE c.schedule_id = d.schedule_id AND job_id = @c_jobid )
        BEGIN
            SELECT @loop_scheduleid= MIN(c.schedule_id) ,@m_scheduleid = MAX(c.schedule_id) 
                FROM  msdb.dbo.sysschedules c ,msdb.dbo.sysjobschedules d
                WHERE c.schedule_id = d.schedule_id AND job_id = @c_jobid 
            WHILE ( @loop_scheduleid <= @m_scheduleid ) 
            BEGIN
                SELECT    @i_schedule_enabled            = [enabled] ,
                        @i_freq_type                = freq_type ,
                        @i_schedule_name            = name,
                        @i_freq_interval            = freq_interval ,
                        @i_freq_subday_type            = freq_subday_type ,
                        @i_freq_subday_interval        = freq_subday_interval ,
                        @i_freq_relative_interval    = freq_relative_interval ,
                        @i_freq_recurrence_factor    = freq_recurrence_factor ,
                        @i_active_start_date        = active_start_date ,
                        @i_active_end_date            = active_end_date ,
                        @i_active_start_time        = active_start_time ,
                        @i_active_end_time            = active_end_time ,
                        @i_schedule_uid                = schedule_uid 
                        FROM msdb.dbo.sysschedules c LEFT JOIN msdb.dbo.sysjobschedules d
                             ON c.schedule_id = d.schedule_id 
                        WHERE d.job_id = @c_jobid AND c.schedule_id = @loop_scheduleid  

                SET @[email protected]+CHAR(13)+CHAR(10) + 'EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @[email protected], @name=N'''+ @i_schedule_name +''',' 
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @enabled='+ CAST(@i_schedule_enabled AS VARCHAR) +',' 
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @freq_type='+ CAST(@i_freq_type AS VARCHAR) +',' 
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @freq_interval='+ CAST(@i_freq_interval AS VARCHAR) +',' 
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @freq_subday_type='+ CAST(@i_freq_subday_type AS VARCHAR) +',' 
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @freq_subday_interval='+ CAST(@i_freq_subday_interval AS VARCHAR) +',' 
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @freq_relative_interval='+ CAST(@i_freq_relative_interval AS VARCHAR) +',' 
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @freq_recurrence_factor='+ CAST(@i_freq_recurrence_factor AS VARCHAR) +',' 
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @active_start_date='+ CAST(@i_active_start_date AS VARCHAR) +',' 
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @active_end_date='+ CAST(@i_active_end_date AS VARCHAR) +',' 
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @active_start_time='+ CAST(@i_active_start_time AS VARCHAR) +',' 
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @active_end_time='+ CAST(@i_active_end_time AS VARCHAR) +',' 
                SET @[email protected]+CHAR(13)+CHAR(10) + '        @schedule_uid=N'''+ @i_schedule_uid +'''' 
                SET @[email protected]+CHAR(13)+CHAR(10) + 'IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback' 

                SET @loop_scheduleid = ( SELECT TOP 1 c.schedule_id FROM msdb.dbo.sysschedules c ,msdb.dbo.sysjobschedules d
                                                WHERE c.schedule_id = d.schedule_id AND job_id = @c_jobid AND c.schedule_id > @loop_scheduleid )  
            END
        END

        SET @[email protected]+CHAR(13)+CHAR(10) + 'EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N''(local)''' 
        SET @[email protected]+CHAR(13)+CHAR(10) + 'IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback' 
        SET @[email protected]+CHAR(13)+CHAR(10) + 'COMMIT TRANSACTION' 
        SET @[email protected]+CHAR(13)+CHAR(10) + 'GOTO EndSave' 
        SET @[email protected]+CHAR(13)+CHAR(10) + 'QuitWithRollback:' 
        SET @[email protected]+CHAR(13)+CHAR(10) + '    IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION' 
        SET @[email protected]+CHAR(13)+CHAR(10) + 'EndSave:' 
        SET @[email protected]+CHAR(13)+CHAR(10) + '' 
        SET @[email protected]+CHAR(13)+CHAR(10) + 'GO'

        PRINT @sql


        insert into master..zzz_temp_JOB_bcp
        SELECT @i_job_name,@sql,@SV,CONVERT(nvarchar(10),getdate(),112)

        FETCH NEXT FROM job INTO @c_jobid ,@c_categoryid ,@SV
    END
    CLOSE job
    DEALLOCATE job



    declare @a nvarchar(17),@c nvarchar(1000),@name nvarchar(100),@d nvarchar(100)
    set @a = CONVERT (nvarchar(17),GETDATE(),112)
    set @name = 'F:\kk_backup\job_'[email protected]+'.sql'
    set @d = 'del ' + @name 
     set @c = 'bcp "select text from master..zzz_temp_JOB_bcp where bak_date = CONVERT(nvarchar(10),getdate(),112)" queryout  "'+ @name +'" -c -S"服務名稱" -U"sa" -P"sa123456" '
     print @d
    print @c



    exec sp_configure 'show advanced options',1
    reconfigure with override
    exec sp_configure 'xp_cmdshell',1
    reconfigure with override

     EXEC master..xp_cmdshell @d
     EXEC master..xp_cmdshell @c



    exec sp_configure 'xp_cmdshell',0

    reconfigure with override

    exec sp_configure 'show advanced options',0

    reconfigure with override
    end
GO
複製程式碼 複製程式碼

 

--------------部落格地址---------------------------------------------------------------------------------------

Expert 診斷優化系列 http://www.cnblogs.com/double-K/

 

 

-----------------------------------------------------------------------------------------------------

 

  總結 : 文章中大部分指令碼針對於中小資料庫,由於工作性質涉及很多客戶部署維護作業,所以力求總結出一套比較完善的指令碼,一鍵部署。

     本文指令碼目前還不完善,後續會不斷補充。另外也請各位看官們貢獻下自己深藏的指令碼,方便大眾,我也取長補短!

     再次感謝!

 ----------------------------------------------------------------------------------------------------

原創連結:http://www.cnblogs.com/double-K/archive/2016/06/02/5538249.html