Различия
Показаны различия между двумя версиями страницы.
| Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
|
stvorennja_v_sql_sistemi_monitoringa_blokuvan [2026/05/01 14:40] tro |
stvorennja_v_sql_sistemi_monitoringa_blokuvan [2026/05/01 14:52] (текущий) tro |
||
|---|---|---|---|
| Строка 87: | Строка 87: | ||
| PRINT ' | PRINT ' | ||
| </ | </ | ||
| + | ===== Крок 3 — процедура моніторингу (живе в MonitoringDB, | ||
| + | < | ||
| + | USE MonitoringDB; | ||
| + | GO | ||
| + | |||
| + | CREATE OR ALTER PROCEDURE dbo.usp_CaptureMonitoring | ||
| + | AS | ||
| + | BEGIN | ||
| + | SET NOCOUNT ON; | ||
| + | DECLARE @CaptureTime DATETIME = GETDATE(); | ||
| + | |||
| + | -- 1. Загальний знімок стану системи | ||
| + | INSERT INTO dbo.SnapshotLog ( | ||
| + | CaptureTime, | ||
| + | SuspendedSessions, | ||
| + | SqlMemoryUsedMb, | ||
| + | ) | ||
| + | SELECT | ||
| + | @CaptureTime, | ||
| + | (SELECT COUNT(*) FROM sys.dm_exec_sessions WHERE is_user_process = 1), | ||
| + | (SELECT COUNT(*) FROM sys.dm_exec_requests WHERE status = ' | ||
| + | (SELECT COUNT(*) FROM sys.dm_exec_requests WHERE status = ' | ||
| + | (SELECT COUNT(*) FROM sys.dm_exec_requests WHERE blocking_session_id > 0), | ||
| + | (SELECT ISNULL(SUM(wait_time), | ||
| + | WHERE wait_type NOT IN (' | ||
| + | p.physical_memory_in_use_kb / 1024, | ||
| + | p.page_fault_count, | ||
| + | p.memory_utilization_percentage | ||
| + | FROM sys.dm_os_process_memory p; | ||
| + | |||
| + | -- 2. Блокування: | ||
| + | INSERT INTO dbo.BlockingLog ( | ||
| + | CaptureTime, | ||
| + | BlockedDB, BlockedHost, | ||
| + | BlockingHost, | ||
| + | BlockedSQL, BlockingSQL, | ||
| + | ) | ||
| + | SELECT | ||
| + | @CaptureTime, | ||
| + | r.session_id, | ||
| + | r.blocking_session_id, | ||
| + | r.wait_type, | ||
| + | r.wait_time / 1000.0, | ||
| + | DB_NAME(r.database_id), | ||
| + | s_blocked.host_name, | ||
| + | s_blocked.login_name, | ||
| + | s_blocked.program_name, | ||
| + | s_blocking.host_name, | ||
| + | s_blocking.login_name, | ||
| + | s_blocking.program_name, | ||
| + | SUBSTRING(t_blocked.text, | ||
| + | SUBSTRING(t_blocking.text, | ||
| + | OBJECT_NAME(t_blocked.objectid, | ||
| + | DATEDIFF(SECOND, | ||
| + | FROM sys.dm_exec_requests r | ||
| + | JOIN sys.dm_exec_sessions s_blocked | ||
| + | JOIN sys.dm_exec_sessions s_blocking | ||
| + | CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t_blocked | ||
| + | OUTER APPLY ( | ||
| + | SELECT SUBSTRING(t.text, | ||
| + | FROM sys.dm_exec_requests r2 | ||
| + | CROSS APPLY sys.dm_exec_sql_text(r2.sql_handle) t | ||
| + | WHERE r2.session_id = r.blocking_session_id | ||
| + | ) t_blocking | ||
| + | LEFT JOIN sys.dm_tran_session_transactions tst ON tst.session_id = r.blocking_session_id | ||
| + | LEFT JOIN sys.dm_tran_active_transactions at ON at.transaction_id = tst.transaction_id | ||
| + | WHERE r.blocking_session_id > 0; | ||
| + | |||
| + | -- 3. Очікування на об' | ||
| + | INSERT INTO dbo.LockLog ( | ||
| + | CaptureTime, | ||
| + | DBName, ObjectName, IndexName, LockType, LockMode, LockStatus, | ||
| + | WaitTimeSec, | ||
| + | ) | ||
| + | SELECT | ||
| + | @CaptureTime, | ||
| + | l.request_session_id, | ||
| + | s.login_name, | ||
| + | s.host_name, | ||
| + | s.program_name, | ||
| + | DB_NAME(l.resource_database_id), | ||
| + | OBJECT_NAME(l.resource_associated_entity_id, | ||
| + | NULL, | ||
| + | l.resource_type, | ||
| + | l.request_mode, | ||
| + | l.request_status, | ||
| + | r.wait_time / 1000.0, | ||
| + | DATEDIFF(SECOND, | ||
| + | SUBSTRING(t.text, | ||
| + | FROM sys.dm_tran_locks l | ||
| + | JOIN sys.dm_exec_sessions s ON l.request_session_id = s.session_id | ||
| + | LEFT JOIN sys.dm_exec_requests r ON r.session_id = l.request_session_id | ||
| + | LEFT JOIN sys.dm_tran_session_transactions tst ON tst.session_id = l.request_session_id | ||
| + | LEFT JOIN sys.dm_tran_active_transactions at ON at.transaction_id = tst.transaction_id | ||
| + | OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) t | ||
| + | WHERE l.resource_type IN (' | ||
| + | AND l.request_status = ' | ||
| + | AND l.resource_database_id > 4; | ||
| + | |||
| + | -- 4. Важкі сесії | ||
| + | INSERT INTO dbo.HeavySessionLog ( | ||
| + | CaptureTime, | ||
| + | DBName, CpuTime, Reads, Writes, WaitType, WaitTimeSec, | ||
| + | ) | ||
| + | SELECT | ||
| + | @CaptureTime, | ||
| + | r.session_id, | ||
| + | s.login_name, | ||
| + | s.host_name, | ||
| + | s.program_name, | ||
| + | DB_NAME(r.database_id), | ||
| + | r.cpu_time, | ||
| + | r.reads, | ||
| + | r.writes, | ||
| + | r.wait_type, | ||
| + | r.wait_time / 1000.0, | ||
| + | DATEDIFF(SECOND, | ||
| + | SUBSTRING(t.text, | ||
| + | FROM sys.dm_exec_requests r | ||
| + | JOIN sys.dm_exec_sessions s ON r.session_id = s.session_id | ||
| + | CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t | ||
| + | WHERE s.is_user_process = 1 | ||
| + | AND ( | ||
| + | r.cpu_time > 5000 | ||
| + | OR r.reads > 100000 | ||
| + | OR r.wait_time > 30000 | ||
| + | ); | ||
| + | |||
| + | -- 5. Очищення даних старше 14 днів | ||
| + | DELETE FROM dbo.BlockingLog | ||
| + | DELETE FROM dbo.LockLog | ||
| + | DELETE FROM dbo.HeavySessionLog WHERE CaptureTime < DATEADD(DAY, | ||
| + | DELETE FROM dbo.SnapshotLog | ||
| + | |||
| + | END; | ||
| + | GO | ||
| + | |||
| + | PRINT ' | ||
| + | </ | ||
| + | ===== Крок 4 — Створюємо SQL Agent Job: ===== | ||
| + | < | ||
| + | USE msdb; | ||
| + | GO | ||
| + | |||
| + | DECLARE @jobId BINARY(16); | ||
| + | |||
| + | EXEC sp_add_job | ||
| + | @job_name = N'1C - Monitoring Capture', | ||
| + | @enabled = 1, | ||
| + | @job_id = @jobId OUTPUT; | ||
| + | |||
| + | EXEC sp_add_jobstep | ||
| + | @job_id = @jobId, | ||
| + | @step_name = N'Run monitoring capture', | ||
| + | @subsystem = N' | ||
| + | @command = N'EXEC MonitoringDB.dbo.usp_CaptureMonitoring;', | ||
| + | @database_name = N' | ||
| + | |||
| + | EXEC sp_add_schedule | ||
| + | @schedule_name = N'1C Monitor Every 2 min', | ||
| + | @freq_type = 4, | ||
| + | @freq_interval = 1, | ||
| + | @freq_subday_type = 4, | ||
| + | @freq_subday_interval = 2; | ||
| + | |||
| + | EXEC sp_attach_schedule | ||
| + | @job_id = @jobId, | ||
| + | @schedule_name = N'1C Monitor Every 2 min'; | ||
| + | |||
| + | EXEC sp_add_jobserver | ||
| + | @job_id = @jobId, | ||
| + | @server_name = N' | ||
| + | |||
| + | GO | ||
| + | |||
| + | SELECT name, enabled, date_created | ||
| + | FROM msdb.dbo.sysjobs | ||
| + | WHERE name = N'1C - Monitoring Capture'; | ||
| + | |||
| + | PRINT 'Job створено успішно'; | ||
| + | </ | ||
| + | ==== Крок 4.1 - запуск завдання вручну (для перевірки) ==== | ||
| + | < | ||
| + | -- Запускаємо вручну | ||
| + | EXEC msdb.dbo.sp_start_job N'1C - Monitoring Capture'; | ||
| + | </ | ||
| + | ==== Крок 4.2 Перевырка успышносты запису ==== | ||
| + | < | ||
| + | -- Перевіряємо що з' | ||
| + | SELECT * FROM MonitoringDB.dbo.SnapshotLog ORDER BY Id DESC; | ||
| + | |||
| + | -- Перевіряємо статус останнього запуску job-а | ||
| + | SELECT | ||
| + | j.name, | ||
| + | h.run_date, | ||
| + | h.run_time, | ||
| + | h.run_duration, | ||
| + | CASE h.run_status | ||
| + | WHEN 0 THEN ' | ||
| + | WHEN 1 THEN ' | ||
| + | WHEN 2 THEN ' | ||
| + | WHEN 3 THEN ' | ||
| + | WHEN 4 THEN ' | ||
| + | END AS run_status, | ||
| + | h.message | ||
| + | FROM msdb.dbo.sysjobs j | ||
| + | JOIN msdb.dbo.sysjobhistory h ON j.job_id = h.job_id | ||
| + | WHERE j.name = N'1C - Monitoring Capture' | ||
| + | ORDER BY h.run_date DESC, h.run_time DESC; | ||
| + | </ | ||
| + | ===== Крок 6 - отримання результатів моніторинга ===== | ||
| + | < | ||
| + | SELECT * FROM MonitoringDB.dbo.BlockingLog | ||
| + | WHERE CaptureTime >= DATEADD(MINUTE, | ||
| + | ORDER BY CaptureTime DESC; | ||
| + | |||
| + | SELECT * FROM MonitoringDB.dbo.HeavySessionLog | ||
| + | WHERE CaptureTime >= DATEADD(MINUTE, | ||
| + | ORDER BY CaptureTime DESC; | ||
| + | </ | ||
| + | |||