|
| 1 | +/* |
| 2 | +<documentation> |
| 3 | + <summary>Create job to resume AG database data movement for suspended databases. |
| 4 | + Create alert to catch when data movement has been suspended, and run the job |
| 5 | + </summary> |
| 6 | + <returns>Create job to resume AG database data movement for suspended databases.</returns> |
| 7 | + <created>2020-08-06 by Wayne Sheffield</created> |
| 8 | + <version>1.0</version> |
| 9 | + <sourceLink>https://github.com/ktaranov/sqlserver-kit/blob/master/Scripts/Job_AG_Resume_Data_Movement.sql</sourceLink> |
| 10 | + <originalLink>https://blog.waynesheffield.com/wayne/archive/2020/08/availability-group-issues-fixed-with-alerts/</originalLink> |
| 11 | +</documentation> |
| 12 | +*/ |
| 13 | + |
| 14 | +USE msdb; |
| 15 | +GO |
| 16 | + |
| 17 | +BEGIN TRANSACTION; |
| 18 | +DECLARE @ReturnCode INT; |
| 19 | +SELECT @ReturnCode = 0;DECLARE @jobname sysname = N'AG - Resume Data Movement'; |
| 20 | +DECLARE @categoryname sysname = 'HADR-Availability Group'; |
| 21 | + |
| 22 | +IF EXISTS (SELECT name FROM dbo.sysjobs where name = @jobname) |
| 23 | +BEGIN |
| 24 | +EXECUTE msdb.dbo.sp_delete_job @job_name = @jobname; |
| 25 | +END; |
| 26 | + |
| 27 | +IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=@categoryname AND category_class=1) |
| 28 | +BEGIN |
| 29 | +EXECUTE @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=@categoryname; |
| 30 | +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback; |
| 31 | +END; |
| 32 | + |
| 33 | + |
| 34 | +EXECUTE @ReturnCode = msdb.dbo.sp_add_job |
| 35 | +@job_name=@jobname, |
| 36 | +@enabled=1, |
| 37 | +@notify_level_eventlog=0, |
| 38 | +@notify_level_email=2, |
| 39 | +@notify_level_netsend=2, |
| 40 | +@notify_level_page=2, |
| 41 | +@delete_level=0, |
| 42 | +@description=N'Resume data movement on suspended Availability Group databases. |
| 43 | +
|
| 44 | +This job can be run manually, or from an alert', |
| 45 | +@category_name=N'HADR-Availability Group', |
| 46 | +@owner_login_name=N'sa'; |
| 47 | +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback; |
| 48 | + |
| 49 | +EXECUTE @ReturnCode = msdb.dbo.sp_add_jobserver @job_name=@jobname, @server_name = N'(local)' |
| 50 | +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback; |
| 51 | + |
| 52 | +EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep |
| 53 | +@job_name=@jobname, |
| 54 | +@step_name=N'Resume data movement in AG databases', |
| 55 | +@step_id=1, |
| 56 | +@cmdexec_success_code=0, |
| 57 | +@on_success_action=1, |
| 58 | +@on_fail_action=2, |
| 59 | +@retry_attempts=0, |
| 60 | +@retry_interval=0, |
| 61 | +@os_run_priority=0, |
| 62 | +@subsystem=N'TSQL', |
| 63 | +@command=N'DECLARE @SQLCMD VARCHAR(1000); |
| 64 | +DECLARE cDBSuspended CURSOR FOR |
| 65 | +SELECT ''ALTER DATABASE ['' + DB_NAME(database_id) + ''] SET HADR RESUME;'' |
| 66 | +FROM sys.dm_hadr_database_replica_states drs |
| 67 | +JOIN sys.availability_replicas ar ON ar.replica_id = drs.replica_id |
| 68 | +WHERE ar.replica_server_name = @@SERVERNAME |
| 69 | +AND drs.is_suspended = 1; |
| 70 | +
|
| 71 | +OPEN cDBSuspended; |
| 72 | +FETCH NEXT FROM cDBSuspended INTO @SQLCMD; |
| 73 | +WHILE @@FETCH_STATUS = 0 |
| 74 | +BEGIN |
| 75 | +EXECUTE (@SQLCMD); |
| 76 | +FETCH NEXT FROM cDBSuspended INTO @SQLCMD; |
| 77 | +END; |
| 78 | +CLOSE cDBSuspended; |
| 79 | +DEALLOCATE cDBSuspended; |
| 80 | +', |
| 81 | +@database_name=N'master', |
| 82 | +@flags=0; |
| 83 | +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback; |
| 84 | + |
| 85 | + |
| 86 | +EXECUTE @ReturnCode = msdb.dbo.sp_update_job |
| 87 | +@job_name=@jobname, |
| 88 | +@enabled=1, |
| 89 | +@start_step_id=1, |
| 90 | +@notify_level_eventlog=0, |
| 91 | +@notify_level_email=2, |
| 92 | +@notify_level_netsend=2, |
| 93 | +@notify_level_page=2, |
| 94 | +@delete_level=0, |
| 95 | +@description=N'Resume data movement on suspended Availability Group databases.', |
| 96 | +@category_name=N'HADR-Availability Group', |
| 97 | +@owner_login_name=N'sa', |
| 98 | +@notify_email_operator_name=N'', |
| 99 | +@notify_netsend_operator_name=N'', |
| 100 | +@notify_page_operator_name=N''; |
| 101 | +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback; |
| 102 | + |
| 103 | +DECLARE @alertname sysname = N'AG Data Movement suspended'; |
| 104 | +IF EXISTS (SELECT * FROM msdb.dbo.sysalerts WHERE name = @alertname) |
| 105 | +BEGIN |
| 106 | +EXECUTE @ReturnCode = msdb.dbo.sp_delete_alert @alertname; |
| 107 | +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback; |
| 108 | +END; |
| 109 | + |
| 110 | +/* |
| 111 | +Alert text: |
| 112 | +AlwaysOn Availability Groups data movement for database '%.*ls' has been suspended for the following reason: "%S_MSG" (Source ID %d; Source string: '%.*ls'). To resume data movement on the database, you will need to resume the database manually. For information about how to resume an availability database, see SQL Server Books Online. |
| 113 | +*/ |
| 114 | +EXECUTE @ReturnCode = msdb.dbo.sp_add_alert |
| 115 | +@name=@alertname, |
| 116 | +@message_id=35264, |
| 117 | +@severity=0, |
| 118 | +@enabled=1, |
| 119 | +@delay_between_responses=0, |
| 120 | +@include_event_description_in=0, |
| 121 | +@job_name = @jobname; |
| 122 | +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback; |
| 123 | + |
| 124 | +COMMIT TRANSACTION; |
| 125 | +GOTO EndSave |
| 126 | +QuitWithRollback: |
| 127 | +IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION; |
| 128 | +EndSave: |
| 129 | +GO |
0 commit comments