Μέσα στην καθημερινότητα ενός DBA είναι να έχει αρκετά schedule tasks με τα οποία κάνει την ζωή του ευκολότερη. Αυτά όπως είναι γνωστό εκτελούνται με την χρήση του SQL Server Agent service. Τα tasks αυτά σε κάθε κύκλο εκτέλεσης τους κάνουν logging την κάθε εκτέλεση σε ένα system table που υπάρχει μέσα στην msdb database και αυτός είναι ο dbo.sysjobhistory. Φυσικό είναι ο πίνακας αυτός να γεμίζει με εγγραφές που έπειτα από κάποιο χρονικό διάστημα πρακτικά είναι άχρηστες καθώς αναφέρονται σε εκτελέσεις που αφορούν το πολύ μακρινό παρελθόν. Πως λοιπόν θα σβήσουμε από αυτόν τον πίνακα τις εγγραφές αυτές που δεν θέλουμε;
Αν πάμε στα Properties του SQL Server Agent και στην επιλογή History οι επιλογές που έχουμε διαθέσιμες είναι αυτές που βλέπουμε και στην εικόνα παρακάτω.
Η default επιλογή είναι να είναι επιλεγμένη η επιλογή Limit size of job history log και οι τιμές είναι όπως φαίνεται και στην εικόνα.
Τι σημαίνουν αυτές όμως:
Maximum job history log size (in rows) σημαίνει ότι στο πίνακα θα πάντα 1000 εγγραφές άσχετα από τον αριθμό των schedule jobs που έχουμε.
Maximum job history rows per job σημαίνει ότι για κάθε job o μέγιστος αριθμός εγγραφών που μπορούν να υπάρξουν είναι 100.
Ας το εξηγήσουμε όμως λίγο καλύτερα αυτό.
Αν για παράδειγμα έχω ένα job που έχει ένα task(step) και το οποίο εκτελείται μια φορά την ημέρα τότε μέσα στο log history θα έχω μέχρι 100 εγγραφές που στην ουσία αντιστοιχούν σε 100 ημέρες.
Αν στο ίδιο job έχω δύο tasks(steps) με το ίδιο schedule τότε θα έχω πάλι 100 εγγραφές αλλά επειδή για κάθε task θα έχω δύο εγγραφές σε κάθε εκτέλεση σημαίνει ότι κρατιέται πληροφορία για 50 ημέρες.
Με αυτά τα απλά μαθηματικά μπορεί κάποιος να βρει σε κάθε job του για πόσες ημέρες μπορεί να κρατήσει ιστορικά στοιχεία για την εκτέλεση του.
Τα πράγματα όμως γίνονται περίπλοκα όταν έχουμε πολλά jobs με πολλά tasks το κάθε ένα μέσα του. Θα πρέπει να κάνεις τους υπολογισμούς ούτως ώστε να καλύψεις τις ανάγκες σου μεγαλώνοντας τον αριθμό των rows που μπορούν να κρατηθούν μέσα στο πίνακα αλλά και τον αριθμό των rows ανά job.
Δεν είναι κάτι δύσκολο αλλά αρκετοί δεν θέλουν να μπουν στην λογική αυτή και απλά επιλέγουν να μην έχουν αυτό τον περιορισμό με το να κάνουν ανενεργή την επιλογή αυτή (uncheck).
Σε αυτή την περίπτωση δεν υπάρχει κανένας περιορισμός απλά μετά από κάποιο χρονικό διάστημα θα έχουμε ένα μεγάλο αριθμό από log entries που αναφέρονται στο παρελθόν που είναι τόσο παλιό που δεν μας χρειάζονται πλέον.
Σε αυτό το σημείο λοιπόν έρχεται η ανάγκη να σβήνουμε αυτές που δεν θέλουμε για παράδειγμα θέλουμε να κρατάμε μόνο όσες έγγραφές είναι τις τελευταίες 90 ημέρες και όλες οι άλλες να διαγράφονται και αυτό θέλουμε να γίνεται με ένα schedule task κάθε εβδομάδα ή μήνα ή σε όποια επιλογή μας.
Βλέποντας την παραπάνω εικόνα με τις διαθέσιμες επιλογές είναι εύκολο να υποθέσουμε ότι απλά κάνοντας check την επιλογή Remove agent history και επιλέγοντας και το χρόνο έχουμε καθαρίσει. Δεν είναι όμως έτσι τα πράγματα.:(
Κάνοντας την παραπάνω ενέργεια και πατώντας ΟΚ στο παράθυρο θα γίνει άπαξ ο καθαρισμός αυτός αλλά δεν θα είναι scheduled όπως αφήνει να εννοηθεί.
Αρκετοί έχουν μπερδευτεί με αυτό και μάλιστα έχουν ανοίξει αυτό σαν bug στο connect, αλλά στα BOL αυτό αναφέρεται.
Θα συμφωνήσω όμως ότι θα έπρεπε να είναι ξεκάθαρο τι ακριβώς θα γίνει με την επιλογή αυτή και να μην αφήνει άλλη εντύπωση. Με αυτή την έννοια είναι παραπλανητικό αλλά bug δεν είναι καθώς είναι documented το τι ακριβώς κάνει.
Τώρα στο πρακτικό θέμα που δεν είναι άλλο από το να σβήνουμε τις εγγραφές που είναι πάνω από το χρονικό διάστημα που επιθυμούμε μπορούμε είτε μέσα από ένα maintenance plan να επιλέξουμε το task History Cleanup Task από το toolbox όπως στην εικόνα παρακάτω
και κάνοντας πάνω στο task right click στις επιλογές που εμφανίζονται στο popup menu EXEC επιλέγουμε Edit και στο διάλογο που μας εμφανίζεται επιλέγουμε μόνο την επιλογή SQL Server Agent job history και το χρόνο που θέλουμε όπως φαίνεται και στην εικόνα παρακάτω
Υπάρχει βέβαια και ένας δεύτερος τρόπος για όσους θέλουν να έχουν τον πλήρη έλεγχο σε αυτό που κάνουν και δεν είναι άλλος από το να φτιάξουν μόνοι τους ένα schedule job το οποίο να έχει ένα task στο οποίο θα εκτελείται η sp_purge_jobhistory και στην οποία θα πρέπει να δίνεται η τελευταία παράμετρος της @oldest_date από την οποία και πίσω θα σβηστούν οι έγγραφές που δεν θέλουμε.
Με βάση το παράδειγμα μας το script για το συγκεκριμένο θα μπορούσε να είναι το παρακάτω
DECLARE @dt datetime
set @dt= dateadd(d,-90,GETDATE())
EXEC msdb.dbo.sp_purge_jobhistory @oldest_date=@dt
/*antonch*/