Στο μάθημα της προηγούμενης εβδομάδας δέχθηκα μια ερώτηση από ένα πολύ καλό φίλο και συνάδελφο (καλημέρα Θεόδωρε) μια αρκετά ενδιαφέρουσα ερώτηση που αφορούσε το που αποθηκεύεται η πληροφορία της διαδικασίας του checkpoint σε μια database.
Επειδή η απάντηση μου τον ξάφνιασε λίγο σε αυτό το post αρχικά θα την μοιραστώ μαζί σας και θα την εξηγήσω.
Είναι αρκετά εύκολο να εντοπίσεις το πότε έχει γίνει checkpoint καθώς για αυτό καταγράφεται το LSN (Log Sequence Number) του στην boot page (page #9) που υπάρχει στο πρώτο data file της κάθε database.
Για να δεις τα περιεχόμενα της συγκεκριμένης σελίδας μπορείς να το κάνεις με την χρήση της DBCC PAGE ή να χρησιμοποιήσεις την DBCC DBINFO
Καλώντας την DBCC DBINFO ως εξής
DBCC DBINFO(‘<DBNAME>’) WITH TABLERESULTS
στα αποτελέσματα που θα πάρουμε ψάχνουμε να βρούμε το dbi_checkptLSN το οποίο περιέχει το checkpoint LSN.
O SQL Server όταν ξεκινάει, όπως είναι γνωστό, πάει σε κάθε database και διαβάσει την boot page και το συγκεκριμένο field ώστε να ξεκινήσει την διαδικασία του recovery στο οποίο ότι transaction είναι ολοκληρωμένο και δεν υπάρχει στα data pages θα το κάνει redo και ότι δεν είναι ολοκληρωμένο θα το κάνει undo.
Όπως έχω πει και γράψει στο παρελθόν η σημασία της boot page είναι αρκετά μεγάλη για τη database και από εκεί ξεκινάει πάντα ο SQL Server.
Θα πρέπει όμως να αναφερθώ και στο transaction log καθώς, ίσως, κάποιος που γνωρίζει πως να το διαβάσει μπορεί να μπερδευτεί και να πιστέψει ότι εκεί γράφεται η συγκεκριμένη πληροφορία.
Πράγματι αν κάποιος διαβάσει το transaction log μιας database χρησιμοποιώντας την fn_dblog θα εντοπίσει records που αναφέρονται στο checkpoint. Είναι αυτά που στο field Operation που η εκτέλεση της fn_dblog επιστρέφει υπάρχει η τιμή LOP_BEGIN_CKPT. Αν συγκρίνει την τιμή του LSN που υπάρχει στο τελευταίο στην σειρά record στο field Current LSN με το dbi_checkptLSN που έχει πάρει από την DBCC DBINFO θα δει ότι είναι το ίδιο.
Από αυτό είναι εύκολο κανείς να παραπλανηθεί και πιστέψει ότι ο SQL Server για να κάνει τη διαδικασία recovery ψάχνει το transaction log. Φυσικά δεν το κάνει καθώς αυτό θα απαιτούσε την σειριακή ανάγνωση του transaction log και αυτό όπως είναι εύκολα κατανοητό θα απαιτούσε χρόνο. Εκτός από αυτό υπάρχει και η περίπτωση που το transaction log μπορεί να είναι χαλασμένο οπότε δεν μπορεί να βασιστεί σε αυτό.
Βέβαια μπορεί κάποιος να πει ότι και η boot page μπορεί να είναι χαλασμένη αλλά αυτό είναι μια άλλη διαδικασία που δεν θα αναφερθώ σε αυτή στο post αυτό.
Γιατί όμως υπάρχει το συγκεκριμένο record στο transaction log;
Η απάντηση σε αυτό το ερώτημα είναι απλή ή θα προσπαθήσω να την κάνω απλή στις γραμμές που ακολουθούν.
Το συγκεκριμένο record υπάρχει στο transaction log με σκοπό να εξυπηρετήσει την ανάγκη που υπάρχει και αφορά το ότι πρέπει να γνωρίζουμε ποια είναι τα transaction που ήταν σε εξέλιξη την στιγμή που έγινε το checkpoint. Μην ξεχνάτε ότι στο transaction log γράφονται όλα σειριακά οπότε…
Αν για παράδειγμα υπάρχει μόνο ένα session πάνω στην database και το οποίο εκτελέσει την εντολή CHECKPOINT με την οποία μπορώ να κάνω force την διαδικασία και αμέσως μετά να δει με την fn_dblog το transaction log και πάει στο τελευταίο record που έχει την τιμή LOP_BEGIN_CKPT θα δει ότι το επόμενο record θα έχει τιμή LOP_END_CKPT το οποίο και σηματοδοτεί την λήξη του checkpoint.
Αν μεταξύ ενός LOP_BEGIN_CKPT και LOP_END_CKPT δούμε record που έχει την τιμή LOP_XACT_CKPT αυτό σημαίνει ότι υπάρχουν ενεργά transactions κατά την διάρκεια του checkpoint ώστε να χρησιμοποιηθεί στην διαδικασία του recovery process.
Δεν θα επεκταθώ περισσότερο καθώς αυτό είναι εκτός θέματος για το συγκεκριμένο post και όπως έχω πει αρκετές φορές υπάρχει ένας θαυμαστός κόσμος στο transaction log που δεν περιγράφεται ούτε με εγκυκλοπαίδεια.
/*antonch*/