Πώς μπορούμε να λαμβάνουμε email όποτε έχουμε υψηλό CPU Usage στον SQL Server
- Πώς ενεργοποιούμε το Unified Auditing σε Oracle Database - 7 Οκτώβριος 2024
- Τι είναι η PostgreSQL και πως κάνουμε μία πλήρης εγκατάσταση - 2 Σεπτέμβριος 2024
- Πώς ρυθμίζουμε το replication του GoldenGate ώστε να διαβάζει από το Standby του Oracle Data Guard - 2 Αύγουστος 2024
Σε αυτό το άρθρο θα δούμε ένα script που δημιουργεί ένα SQL Server Agent Job το οποίο θα μας ενημερώνει με email όποτε το CPU ξεπεράσει ένα threshold. Την πληροφορία την αντλέι όχι από performance counters του λειτουργικού αλλά από το default Extended Event του system_health που υπάρχει στην κάθε εγκατάσταση SQL Server.
Τα βήματα
Για αρχή θα πρέπει να έχουμε ενεργοποιήσει το Database Mail στον SQL Server. Το πως γίνεται αυτό το έχουμε δει σε αυτό το άρθρο.
Το Transact SQL Script
Με το παρακάτω script που έχω ετοιμάσει, θα φτιαχτεί ένα SQL Server Agent Job το οποίο θα τρέχει άνα 5 λεπτά και θα ελέγχει πόσο είναι το CPU Usage μέσα από το system_health Extended Event. Αν ξεπερνάει το threshold που έχουμε ορίσει στον κώδικα θα στέλνει email με το profile που έχουμε ορίσει.
Τις μόνες πληροφορίες που χρειάζεται να αλλάξουμε ανά περίπτωση είναι (γραμμή 59):
IF cast(@usage as int) > 95 <----- The limit / threshold of CPU Usage that we want to send us emails above
begin
exec msdb.dbo.sp_send_dbmail
@profile_name = ''gmail'', <----- The profile name we made to send email in the first step
@recipients = ''info@dataplatform.gr'', <----- And the recipients of the email
@subject = @sub,
@body = @bod;
end;
Αφού κάνουμε τις παραπάνω τροποποιήσεις στο παρακάτω script, μένει απλά να τρέξουμε σε ένα καινούργιο query window στο instance:
USE [msdb] GO /****** Object: Job [Alert for high CPU] Script Date: 29/10/2021 05:00:31 ìì ******/ BEGIN TRANSACTION DECLARE @ReturnCode INT SELECT @ReturnCode = 0 /****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 29/10/2021 05:00:31 ìì ******/ 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'Alert for high CPU', @enabled=1, @notify_level_eventlog=0, @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'sa', @job_id = @jobId OUTPUT IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback /****** Object: Step [step1] Script Date: 29/10/2021 05:00:31 ìì ******/ EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'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'set ansi_warnings on go set ansi_padding on go set quoted_identifier on go declare @usage int, @sub nvarchar(max), @bod nvarchar(max) set @usage = ( SELECT 100-avg(record.value(''(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]'', ''INT'')) as ''Cpu Usage %'' FROM ( SELECT top 5 CONVERT(xml, record) AS [record],dateadd (ms,timestamp - (select ms_ticks from sys.dm_os_sys_info),getdate()) as ''Time'' FROM sys.dm_os_ring_buffers WHERE ring_buffer_type = N''RING_BUFFER_SCHEDULER_MONITOR'' AND record LIKE ''%<SystemHealth>%'' order by time desc) AS x) ; set @sub = (select ''SQL Server Alert System: High CPU Usage at '' + @@servername); set @bod = (select ''DESCRIPTION: At '' + cast(getdate() as nvarchar) +'' on SQL Server '' + @@servername +'', CPU usage was '' +cast(@usage as nvarchar)+ ''%!!!!''); IF cast(@usage as int) > 95 begin exec msdb.dbo.sp_send_dbmail @profile_name = ''gmail'', @recipients = ''info@dataplatform.gr'', @subject = @sub, @body = @bod; end; ', @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'daily', @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=20211029, @active_end_date=99991231, @active_start_time=0, @active_end_time=235959, @schedule_uid=N'df24cb48-55e9-436a-a0de-56d4dd5139a3' 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
Όταν το τρέξουμε θα δούμε στον Object Explorer του SQL Server Management Studio ότι έχει δημιουργήσει ένα καινούργιο Job στον SQL Server Agent:
Μετά από λίγο θα δούμε ότι έστειλε μόνο του χωρίς να κάνουμε κάτι άλλο email για High CPU Usage (για το παράδειγμα άλλαξα το threshold από πάνω από 95% σε 10% για να σταλεί):