Overview
Η εκτέλεση προγραμματισμένων εργασιών με την χρήση του SQL Agent είναι κάτι που σπάνια δεν θα βρει κάποιος σε ένα instance.
Αυτό σημαίνει ότι πρέπει να κάνουμε monitor, management & troubleshooting για όλες τις προγραμματισμένες εργασίες που εκτελούνται στο SQL Agent.
Για να κάνουμε αυτό έχουμε αρκετά εργαλεία στα χέρια μας όπως τα Job Activity Monitor και Job View History UI tools μέσα από τον SSMS και το ADS και φυσικά τα object views που υπάρχουν στην msdb database όπως για παράδειγμα τα dbo.sysjobhistroy και dbo.sysjobactivity.
Με αυτά χρόνια κάνουμε τι δουλεία μας χρόνια τώρα και την κάνουμε καλά αλλά υπάρχουν και αυτές οι περιπτώσεις που χρειάζεται το κάτι παραπάνω σε πληροφορία για να είμαστε σε θέση να κάνουμε monitor, management & troubleshooting.
Για αυτές έχουνε φτιάξει/συνδυάσει τις πληροφορίες που τα διάφορα DMVs/DMFs/System Objects/Views μας δίνουν ώστε να λάβουμε αυτό που θέλουμε. Μία από αυτές τι περιπτώσεις περιγράφω στο άρθρο μου αυτό.
The case
Έχουμε συνηθίσει για τα sessions και τα queries που αυτά εκτελούν σε κάποια χρονική στιγμή να χρησιμοποιούμε διάφορες stored procedures όπως sp_who, sp_who2, sp_whoisactive ή να γράφουμε δικές μας υλοποιήσεις που να χρησιμοποιούν διάφορα DMVs για μπορούμε να κάνουμε monitor και troubleshooting.
Δυστυχώς αν θελήσουμε να κάνουμε το ίδιο μόνο για τα sessions που «έρχονται» από τα SQL Agent jobs δεν έχουμε κάτι «έτοιμο». Επίσης να τονίσω ότι τα Job Activity Monitor, Job View History UI tools μέσα από τον SSMS και το ADS και τα dbo.sysjobhistroy, dbo.sysjobactivity δεν μου επιστρέφουν τα session_id, waits κ.λπ. πληροφορίες που είναι χρήσιμες.
Τhe View
Για το λόγο αυτό έφτιαξα το παρακάτω view το οποίο μου επιστρέφει άμεσα με την εκτέλεση μόνο των SQL Agent T-SQL jobs/tasks με κάποιες πληροφορίες που θεωρώ προσωπικά σημαντικές και που φυσικά μπορείτε να προσθέσετε και άλλες.
Όπως θα δείτε δεν είναι κάτι περίπλοκο και δεν χρησιμοποιεί κάτι άγνωστο. Απλά κάνω χρήση των δύο γνωστών και αρκετά βασικών DMVs (sys.dm_exec_sessions, sys.dm_exec_request) τα οποία φιλτράρω μόνο για το SQL Agent jobs και με ένα απλό parsing λαμβάνω το jobid και stepid ώστε να είμαι σε θέση να κάνω join με τον dbo.sysjobs για να πάρω το όνομα του.
Installation
Όπως θα δείτε το συγκεκριμένο view έχω επιλέξει να το έχω στην msdb database σε ένα schema dba καθώς αυτή είναι η βάση που χρησιμοποιεί το SQL Agent service, φυσικά ο καθένας μπορεί να το τοποθετήσει σε οποία θέλει αλλά θεωρώ ότι αυτό είναι το σωστό.
Script
SQL Script
use msdb;
go
if not exists ( select * from sys.schemas where name='dba')
begin
exec ('create schema dba')
end
go
create or alter view dba.sqlagent_tsql_jobs_requests
as
select
s.session_id
, r.blocking_session_id
, s.login_time
, j.[name] as job_name
, cast(
replace(
replace(
right (s.program_name,len(s.program_name)-charindex(':',s.program_name))
,'Step',''
)
,')','')
as int
) as job_step_id
, s.host_name
, s.host_process_id
, s.login_name
, r.status
, r.command
, r.wait_resource
, r.sql_handle
from
sys.dm_exec_sessions as s
inner join
sys.dm_exec_requests as r on r.session_id = s.session_id
cross apply
(
select trim(left(replace (s.program_name,'SQLAgent - TSQL JobStep (Job ',''),
charindex(':',replace (s.program_name,'SQLAgent - TSQL JobStep (Job ','')) - 1)
)
) as jid(job_id)
inner join
msdb.dbo.sysjobs as j on convert(varchar(max), convert(binary(16), j.job_id), 1) = jid.job_id
where
is_user_process = 1
and
s.program_name like 'SQLAgent - TSQL JobStep (Job %'
go
Usage
Για την χρήση απλά εκτελοούμε το παρακάτω query
SQL Script
select * from dba.sqlagent_tsql_jobs_requests