數據庫運維中盛傳一個小段子,我誤刪除了數據庫,改怎麼辦?有備份還原備份,沒有備份就準備簡歷!聽起來有趣但發生在誰身上,誰都笑不起來。接觸了不少的客戶發現90%客戶的運維策略都不是很完善。本篇就分享一些常規的運維腳本,本篇沒有涉及到的或不足的也請你們留言無私貢獻深藏多年的腳本,謝謝!sql
郵件主要用來監控做業是否運行成功,若是您已經配置了相似zabbix等軟件請忽略。shell
--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 = 'kk_XXXX@163.com' -- 發件人郵件地址 ,@display_name = null -- 發件人姓名 ,@replyto_address = null ,@description = null ,@mailserver_name = 'smtp.163.com' -- 郵件服務器地址 ,@mailserver_type = 'SMTP' -- 郵件協議(SQL 2005 只支持 SMTP) ,@port = 25 -- 郵件服務器端口 ,@username = 'kk_XXXX@163.com' -- 用戶名 ,@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 = 'kk_XXXX@163.com;kk2_XXXX@163.com' -- 收件人郵箱 ,@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
注 :操做員可根據是否在做業成功或失敗時通知,後續腳本均未配置操做員,如需配置可在做業屬性中自行添加 網絡
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 = 'KK_XXX@163.COM', --收件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小時一次差別備份、一小時一第二天志備份。ide
存儲過程建立後會保留在master庫中,存儲過程主要控制備份邏輯,備份路徑等。oop
存儲過程當中只有一個類型參數,用於控制全備/差別/日誌備份,可根據須要修改。測試
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_'+@dateTime+'.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
備份做業很簡單,就是調用存儲過程用計劃控制備份頻率fetch
-- 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 @job_id=@jobId, @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 @job_id=@jobId, @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 @job_id=@jobId, @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 @job_id=@jobId, @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 @job_id=@jobId, @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 @job_id=@jobId, @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 @job_id=@jobId, @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 @job_id=@jobId, @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
備份做業能夠經過備份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 a.job_id=@c_jobid AND a.category_id = @c_categoryid SET @sql=@sql+CHAR(13)+CHAR(10) + 'USE [msdb]' SET @sql=@sql+CHAR(13)+CHAR(10) + 'GO' SET @sql=@sql+CHAR(13)+CHAR(10) + '/****** Object: Job ['+ @i_job_name +'] Script Date: '+CONVERT(VARCHAR,GETDATE(),22)+' ******/' SET @sql=@sql+CHAR(13)+CHAR(10) + 'BEGIN TRANSACTION' SET @sql=@sql+CHAR(13)+CHAR(10) + 'DECLARE @ReturnCode INT' SET @sql=@sql+CHAR(13)+CHAR(10) + 'SELECT @ReturnCode = 0' SET @sql=@sql+CHAR(13)+CHAR(10) + '/****** Object: JobCategory ['+ @i_category_name +'] Script Date: 08/20/2016 12:35:16 ******/' SET @sql=@sql+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 @sql=@sql+CHAR(13)+CHAR(10) + 'BEGIN' SET @sql=@sql+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 @sql=@sql+CHAR(13)+CHAR(10) + 'IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback' SET @sql=@sql+CHAR(13)+CHAR(10) + '' SET @sql=@sql+CHAR(13)+CHAR(10) + 'END' SET @sql=@sql+CHAR(13)+CHAR(10) + '' SET @sql=@sql+CHAR(13)+CHAR(10) + 'DECLARE @jobId BINARY(16)' SET @sql=@sql+CHAR(13)+CHAR(10) + 'EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'''+ @i_job_name +''',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @enabled='+ CAST(@i_enabled AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @notify_level_eventlog='+ CAST(@i_notify_level_eventlog AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @notify_level_email='+ CAST(@i_notify_level_email AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @notify_level_netsend='+ CAST(@i_notify_level_netsend AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @notify_level_page='+ CAST(@i_notify_level_page AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @delete_level='+ CAST(@i_delete_level AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @description=N'''+ @i_description +''',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @category_name=N'''+ @i_category_name +''',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @owner_login_name=N'''+ @i_owner_login_name +''', @job_id = @jobId OUTPUT' SET @sql=@sql+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 @sql=@sql+CHAR(13)+CHAR(10) + '/****** Object: Step ['+ @i_step_name +'] Script Date: '+CONVERT(VARCHAR,GETDATE(),22)+' ******/' SET @sql=@sql+CHAR(13)+CHAR(10) + 'EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'''+ @i_step_name +''',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @step_id='+ CAST(@i_step_id AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @cmdexec_success_code='+ CAST(@i_cmdexec_success_code AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @on_success_action='+ CAST(@i_on_success_action AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @on_success_step_id='+ CAST(@i_on_success_step_id AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @on_fail_action='+ CAST(@i_on_fail_action AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @on_fail_step_id='+ CAST(@i_on_fail_step_id AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @retry_attempts='+ CAST(@i_retry_attempts AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @retry_interval='+ CAST(@i_retry_interval AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @os_run_priority='+ CAST(@i_os_run_priority AS VARCHAR) +', @subsystem=N'''+ @i_subsystem +''',' SET @sql=@sql+CHAR(13)+CHAR(10) + ISNULL(' @command=N''' + REPLACE(@i_command ,'''' ,'''''') + ''',' ,'') SET @sql=@sql+CHAR(13)+CHAR(10) + ISNULL(' @database_name=N'''+ @i_database_name +''',' ,'') SET @sql=@sql+CHAR(13)+CHAR(10) + ' @flags='+ CAST(@i_flags AS VARCHAR) SET @sql=@sql+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 @sql=@sql+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 @sql=@sql+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 @sql=@sql+CHAR(13)+CHAR(10) + 'EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'''+ @i_schedule_name +''',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @enabled='+ CAST(@i_schedule_enabled AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @freq_type='+ CAST(@i_freq_type AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @freq_interval='+ CAST(@i_freq_interval AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @freq_subday_type='+ CAST(@i_freq_subday_type AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @freq_subday_interval='+ CAST(@i_freq_subday_interval AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @freq_relative_interval='+ CAST(@i_freq_relative_interval AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @freq_recurrence_factor='+ CAST(@i_freq_recurrence_factor AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @active_start_date='+ CAST(@i_active_start_date AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @active_end_date='+ CAST(@i_active_end_date AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @active_start_time='+ CAST(@i_active_start_time AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @active_end_time='+ CAST(@i_active_end_time AS VARCHAR) +',' SET @sql=@sql+CHAR(13)+CHAR(10) + ' @schedule_uid=N'''+ @i_schedule_uid +'''' SET @sql=@sql+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 @sql=@sql+CHAR(13)+CHAR(10) + 'EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N''(local)''' SET @sql=@sql+CHAR(13)+CHAR(10) + 'IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback' SET @sql=@sql+CHAR(13)+CHAR(10) + 'COMMIT TRANSACTION' SET @sql=@sql+CHAR(13)+CHAR(10) + 'GOTO EndSave' SET @sql=@sql+CHAR(13)+CHAR(10) + 'QuitWithRollback:' SET @sql=@sql+CHAR(13)+CHAR(10) + ' IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION' SET @sql=@sql+CHAR(13)+CHAR(10) + 'EndSave:' SET @sql=@sql+CHAR(13)+CHAR(10) + '' SET @sql=@sql+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_'+@a+'.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/
-----------------------------------------------------------------------------------------------------
總結 : 文章中大部分腳本針對於中小數據庫,因爲工做性質涉及不少客戶部署維護做業,因此力求總結出一套比較完善的腳本,一鍵部署。
本文腳本目前還不完善,後續會不斷補充。另外也請各位看官們貢獻下本身深藏的腳本,方便大衆,我也取長補短!
再次感謝!
----------------------------------------------------------------------------------------------------
注:此文章爲原創,歡迎轉載,請在文章頁面明顯位置給出此文連接!
若您以爲這篇文章還不錯請點擊下右下角的推薦,很是感謝!