Αφορμή για το άρθρο αυτό είναι το ερώτημα ενός μέλους του SQLschool.gr το οποίο αφορούσε το transaction log maintenance και ιδιαίτερα του shrink αυτού μιας database που είναι σε Availability Group.
AlwaysOn Availability Group
Σε ένα AlwaysOn Availability Group (AG) έχω περισσότερα από δύο SQL Server instances όπου το ένα είναι το Primary node και το άλλο ή τα άλλα το secondary(ries) node(s).
Επίσης σε ένα AG μπαίνει μια η περισσότερες databases και αυτή είναι σε Full Recovery model καθώς αυτό μόνο υποστηρίζεται σε AG.
Τέλος κάθε database μπορεί να είναι είτε σε full sync mode που σημαίνει ότι ενέργεια γίνεται στο primary θα πρέπει να ενημερώσει το secondary για να θεωρηθεί ολοκληρωμένη είτε σε async mode που σημαίνει ότι όποια ενέργεια γίνεται στο primary θεωρείται ολοκληρωμένη και ασύγχρονα ενημερώνετε το secondary.
Για την υλοποίηση αυτών ο SQL Server χρησιμοποιεί το transaction log και στην ουσία μεταφέρει από το primary στο secondary Log Blocks. Όπως έχω αναφέρει σε προηγούμενο άρθρο μου ένα Log Block είναι μια συλλογή (container) από Log Records που έχουν γίνει από μια συγκεκριμένη ενέργεια.
Με όσο το δυνατόν απλά και περιγραφικά λόγια μπορώ να το πω η διαδικασία έχει ως εξής:
Κάθε φορά που γίνεται μια transactional ενέργεια στον primary ο secondary ζητάει τα log blocks που περιέχουν τα log records της ενέργειας αυτής. Τότε ενεργοποιείται στο primary ένας log scanner worker οποίος με βάση τα LSNs που λείπουν από τον secondary δίνει σε αυτό τα αντίστοιχα Log Blocks.
Αυτό σημαίνει ότι όταν η ενέργεια που έχει γίνει έχει μεγάλο όγκο από Log Blocks αυτά θα πρέπει μεταφερθούν και γραφτούν στο secondary και εδώ παίζει μεγάλη σημασία το network.
Shrink Transaction Log on AG
Για να μπορεί να γίνει shrink το transaction log θα πρέπει να είναι ελεύθερα τα VLFs που είναι στο τέλος αυτού.
Κάτι τέτοιο μπορεί κανείς να το δει με τη DBCC LOGINFO η οποία επιστρέφει τον αριθμό των VLFs που υπάρχουν στην εκάστοτε database και καταλαβαίνουμε αν αυτά είναι δεσμευμένα ή όχι αν στη στήλη Status είναι την τιμή 2 (δεσμευμένο) ή 0 (ελεύθερο).
Για να ελευθερωθεί κάποιο VLF θα πρέπει να κάνουμε transaction log backup και εφόσον αυτό δεν περιέχει active transactions καθαρίζεται και μπορεί να επαναχρησιμοποιηθεί. Αυτό πραγματικά γίνεται πάντα εκτός από την περίπτωση που έχω την database σε AG/
Lazy Log Truncation
Στην περίπτωση αυτή έχω αυτό που ονομάζεται Lazy Log Truncation που "μαρκάρει" το VLF σαν υποψήφιο για truncation αλλά δεν το κάνει μέχρι αυτό πραγματικά να μην χρειάζεται.
Αυτό το κάνει για να έχει την δυνατότητα στην περίπτωση που θα προστεθεί ένα νέο secondary να χρειαστούν το δυνατό λιγότερα transaction log backups/restores.
Το πότε αυτά θα φύγουν είναι κάτι το οποίο θα πάρει κάποιο χρόνο (μπορεί λεπτά μπορεί και ώρες). Αυτός είναι και ο λόγος που δεν είναι πάντα άμεσα εφικτό να κάνουμε shrink το transaction log σε μια database που είναι σε AG.
Transaction Log Maintenance in AG
Αρχικά για ΑΚΟΜΑ ΜΙΑ ΦΟΡΑ να ΤΟΝΙΣΩ ΟΣΟ ΠΕΡΙΣΣΟΤΕΡΟ ΜΠΟΡΩ OΤΙ ΠΡΕΠΕΙ ΝΑ ΣΤΑΜΑΤΗΣΕΤΕ ΤΟ ΟΠΟΙΑΔΗΠΟΤΕ SHRINK OPERATION ΚΑΝΕΤΕ ΣΤΗΝ DATABASE. Περισσότερο κακό κάνετε παρά καλό και το έχω γράψει εδώ στο SQLschool.gr αρκετές φορές.
Πέρα όμως από αυτό θα πρέπει να είστε προετοιμασμένοι όταν βάζετε μια database σε AG ότι θα χρειάζεστε περισσότερο χώρο για το transaction log για αυτή.
Για να κρατήσετε τον χώρο αυτό σε χαμηλά μεγέθη θα πρέπει να κάνετε συχνότερα transaction log backups που ενδεχομένως να είναι και ανά 5-10 λεπτά ανάλογα με το φορτίο που έχει η κάθε database.
Τέλος θα πρέπει να γίνει πλήρως κατανοητό ότι εργασίες όπως rebuild/reorg indexes θα αυξήσουν τον χώρο του transaction log και θα πρέπει να τις λάβετε υπόψη όταν κάνει size estimation για αυτό.
Ελπίζω όλα τα παραπάνω να βοηθήσουν την καθημερινότητα σας με το transaction log μιας database που είναι σε AG.
//antonch