Μπορεί ο τίτλος στο συγκεκριμένο άρθρο μου να είναι άκρως Σαιξπηρικός αλλά αντικατοπτρίζει πλήρως την σύγχυση που υπάρχει γύρω από το αν πρέπει ή όχι να γίνεται shrink σε μια database.
Δεν είναι λίγες οι φορές που έχω κατηγορηθεί για την επιμονή μου ότι κάτι τέτοιο δεν είναι καλό να γίνεται. Δεν είναι επίσης λίγες οι φορές που στην δουλειά μου έχω αρνηθεί να κάνω κάτι τέτοιο. Όπως επίσης δεν είναι λίγες οι φορές που έχω χαρακτηριστεί απόλυτος στο συγκεκριμένο θέμα. Τέλος είναι αμέτρητες οι φορές που έχω ερωτηθεί για την άποψη μου σχετικά με αυτό.
Αρχικά θα πρέπει να ξεκαθαρίσω ότι δεν είμαι απόλυτος και αρνητικός σχετικά με το shrink, αρκεί αυτό να γίνεται εφόσον έχουμε αποδεδειγμένα κατανοήσει τι ακριβώς θέλουμε να πετύχουμε και επιπρόσθετα έχουμε αποδεδειγμένο όφελος από αυτό.
Τέλος είναι σημαντικό να γνωρίζουμε πως αυτό δουλεύει πριν πατήσουμε το κουμπί που θα ξεκινήσει την διαδικασία καθώς επίσης πρέπει να γνωρίζουμε τα υπέρ και τα κατά που θα πρέπει να αντιμετωπίσουμε μετά από το τέλος της διαδικασίας.
Πώς δουλεύει το shrink;
Με το shrink αυτό που γίνεται είναι να γίνονται remove τα μη χρησιμοποιούμενα pages (unused pages) που έχει κάθε file (data / log ) με αποτέλεσμα να μειώνεται το μέγεθος του αρχείου στο δίσκο.
Για να γίνει όμως αυτό θα πρέπει όλα τα unused pages να είναι στο τέλος του κάθε αρχείου.
Αυτό σημαίνει ότι μία βασική εργασίας της διαδικασίας είναι να μεταφέρει τα used pages σε σημείο τέτοιο (στην αρχή του αρχείου) που να δημιουργεί μια ακολουθία από used pages και όλα τα unused pages στο τέλος του αρχείου ώστε να δημιουργηθεί η αντίστοιχη ακολουθία για τα unused pages.
Ποιο είναι το αποτέλεσμα του shrink;
Μπορεί στο τέλος της διαδικασίας να έχουμε μικρότερο μέγεθος στο δίσκο της database και να είμαστε χαρούμενοι για αυτό αλλά έχουμε και heavily fragmented indexes, που σημαίνει και κακό query performance.
Αυτός είναι και ο κυρίαρχος λόγος που οι περισσότεροι συμβουλεύουν να μην γίνεται.
Η τελευταία μου πρόταση είναι και αυτή που έχει δημιουργήσει αυτό τον κακό χαμό γύρω από το θέμα.
Κάποιοι το έχουν ρίξει στο πυρ της κολάσεως, άλλοι αντιμάχονται αυτό και τέλος κάποιοι άλλοι κάθονται και τους κοιτάνε να αναλώνονται σε ατελείωτες αντιπαραθέσεις και απλά γελάνε, καθώς γνωρίζουν πως καλά να χρησιμοποιήσουν την δυνατότητα αυτή ανάλογα με την περίπτωση
Shrink Options
Auto Shrink option
Αρχικά θα ξεκινήσω με το auto shrink option που υπάρχει σε κάθε database, το οποίο by default είναι OFF και καλό θα είναι να μείνει off, ιδιαίτερα σε production environment.
Είναι η μόνη περίπτωση που είμαι απόλυτος. Ουσιαστικό κέρδος δεν θα έχει κανείς με αυτό, το αντίθετο μάλιστα θα έχει performance penalty καθώς κάθε φορά που θα χρειαστεί περισσότερος χώρος για μεγαλώσει η database θα έχω ΙΟ το οποίο ΙΟ θα έχω και όταν θα πρέπει να μειωθεί.
Shrink database option
Κάνει όλη την database (data & log) shrink με τα καλά και τα κακά που ανέφερα και πριν.
Shrink file option
Κάνει shrink συγκεκριμένο data file ή log.
Περιπτωσιολογία
Σαν γενικότερη αρχή καλό είναι να μην κάνουμε shrink database δηλαδή όλη την database.
Υπάρχουν όμως περιπτώσεις που πρέπει όπως αν για παράδειγμα για κάποιο λόγο, πχ κάποιο bug, μεγάλωσε δυσανάλογα η database.
To να κάνει κανείς shrink database σε μια τέτοια περίπτωση δεν είναι αμαρτία, αρκεί φυσικά μετά να κάνει rebuild/reorganize τους index.
Όμως το να κάνει αυτό σε σαν schedule task είναι μεγάλη αμαρτία και υποδηλώνει πολλά άσχημα πράγματα που αφορούν σχεδιασμό στη database και πολλά ακόμα.
Επίσης σε μια τέτοια περίπτωση καλό θα είναι μετά την ολοκλήρωση της διαδικασίας του shrink & index rebuild/reorg να δει κανείς τι τελικά κερδίζει σε χώρο σε σχέση με το χρόνο και τα resources που έχουν δαπανηθεί για αυτή.
Aν είναι πραγματικά μεγάλος τότε ίσως αξίζει να γίνει schedule task. Σε διαφορετική περίπτωση δεν αξίζει να γίνει ξανά η διαδικασία.
Ξέρω ότι θα με ρωτήσετε τι σημαίνει κέρδος;
Θα απαντήσω ότι εφόσον ο χώρος που θα ελευθερωθεί είναι πάνω από το 50% ναι αξίζει. Όμως πάντα υπάρχει ακόμα κάτι που πρέπει να ελεγχθεί. Τι είναι αυτό;
Μα φυσικά το γιατί η βάση μεγαλώνει σε βαθμό που δεν χρειαζόμαστε. Μήπως γιατί έχουμε ορίζει λάθος το growth αυτής;
Μήπως βάζουμε δεδομένα που ουσιαστικά είναι άχρηστα και που ουσιαστικά δεν τα χρειαζόμαστε;
Από την εμπειρία μου όλα αυτά είναι οι παράγοντες που κάνουν μια βάση να φουσκώνει πέρα από τα συνηθισμένα.
Πρώτος παράγοντας είναι να έχουν ορισθεί auto growth τιμές πέρα από την πραγματικότητα και αυτό γιατί κάποιος δεν έχει κάνει σωστό sizing estimation.
Επίσης αρκετοί στο auto growth βάζουν ποσοστιαία τιμή, κάτι που κάνει το μέγεθος να αυξάνει δυσανάλογα. Αν αυτό ορισθεί σωστά τότε δεν θα υπάρξει ποτέ μα ποτέ η ανάγκη να γίνει shrink η βάση.
Οι περισσότεροι συνηθίζουν (ίσως και να είναι απαραίτητο) μέσα στην βάση να έχουν διάφορους πίνακες που η δουλειά τους είναι:
- είτε για μια φορά
- είτε να χρησιμοποιούνται σαν stage tables
- είτε να είναι πίνακες που να κρατάνε logs.
Τα δεδομένα σε αυτούς τους πίνακες μπορεί να αυξηθούν απρόβλεπτα και φυσικά να μεγαλώσουν το μέγεθος της βάσης.
Επειδή λοιπόν για αυτούς τους πίνακες είναι εξ αρχής γνωστή η χρήση τους και είναι σίγουρο ότι κάποια στιγμή θα χρειαστεί να προχωρήσουμε σε ολική ή μερική διαγραφή δεδομένων είναι και εύκολο να τους βάλουμε σε ξεχωριστό filegroup.
Το κέρδος σε αυτή την περίπτωση είναι μεγάλο καθώς μπορούμε να κάνουμε shrink μόνο τo αρχείο ή τα αρχεία που υπάρχουν στο συγκεκριμένο filegroup και που περιέχουν τα δεδομένα των πινάκων αυτών χωρίς να πειράξουμε την βάση ολόκληρη. Δεν μπορώ πραγματικά να καταλάβω γιατί οι περισσότεροι επιμένουν να έχουν μόνο έναν data file στην βάση τους.
Αρκετοί ρωτάνε για το shrink στο transaction log. Η απάντηση μου και εδώ είναι απλή. Εφόσον το αυτό μεγαλώσει απρόσμενα μπορούν να κάνουν shrink file και να επιλέξουν μόνο το transaction log. Ίσως είναι η πιο ξεκάθαρη περίπτωση, βέβαια καλό θα είναι να υπάρχει και backup.
Αρκετοί επίσης λένε ότι πριν πάρεις backup θα πρέπει να κάνεις shrink γιατί έτσι θα έχεις και μικρότερο μέγεθος στο backup. Παντελώς λάθος.
Το backup παίρνει μόνο τις σελίδες που έχουν δεδομένα και όχι αυτές που είναι άδειες.
Αν για παράδειγμα έχω μια βάση που είναι 100ΜΒ δηλαδή έχει 12800 σελίδες των 8ΚΒ και από αυτές μόνο οι 800 είναι που έχουν δεδομένα τότε το backup θα είναι 800 σελίδες Χ 8ΚΒ.
Μερικές συμβουλές
Μερικές συμβουλές που θα ήθελα να δώσω στο συγκεκριμένο θέμα και πάντα αναφερόμενος σε παραγωγικά περιβάλλοντα.
- Δεν ενεργοποιούμε ποτέ το auto shrink option σε μια database. Περισσότερο κακό κάνει παρά κάλο, ιδιαίτερα σε performance.
- Δεν είναι καλό να γίνεται το shrink schedule task.
- Μπορούμε να κάνουμε έστω μια φορά shrink αλλά μετά θα πρέπει να κάνουμε index rebuild/reorg ΚΑΙ θα πρέπει να δούμε τι τελικά έχουμε κερδίζει σε χώρο. Αν είναι κάτω από το 50% τότε δεν υπάρχει λόγος να κάνουμε ξανά shrink την βάση αυτή.
- Σχεδιάζουμε σωστά την βάση μας ώστε οι πίνακες που κάποια στιγμή σε αυτούς θα διαγράψουμε δεδομένα να είναι σε ξεχωριστά files ώστε να μπορούμε να κάνουμε shrink file αντί για όλη την βάση. Για αυτό επειδή ξέρω ότι αρκετοί έχετε κληρονομήσει αρκετές βάσεις και δεν είναι όπως είπα μπορείτε να ξεκινήσετε την μεταφορά των πινάκων αυτών κάνοντας χρήση των όσων έχω γράψει στο άρθρο μου "Moving a table to another filegroup"
Επειδή θα υπάρξουν ερωτήσεις παρακαλώ αυτές να τοποθετηθούν στο sqlschool.gr και όχι στα διάφορα socials που αυτό θα τοποθετηθεί.
/*antonch*/