go backsqlschool blogs list

How to use specific values in parameters of fn_dblog function

by Antonios Chatzipavlis

Μια από τις αγαπημένες functions που την χρησιμοποιώ αρκετά συχνά ιδιαίτερα σε περιπτώσεις που υπάρχει κάποιο πρόβλημα με συγκεκριμένη βάση είναι η fn_dblog.

Παρόλο που είναι μια undocumented function εντούτοις είναι ευρέως γνωστή και φυσικά χρησιμοποιούμενη σε όσους σοβαρά ασχολούνται με τον SQL Server.

Φυσικά είναι μια εναλλακτική λύση για να διαβάσεις τα περιεχόμενα του transaction log καθώς υπάρχουν και άλλοι τρόποι όπως η DBCC LOG και η DBCC LOGINFO που και αυτές είναι undocumented.

Αυτό που με κάνει να χρησιμοποιώ την fn_dblog() είναι το γεγονός ότι μπορώ να πάρω τα δεδομένα μου σε μορφή table χωρίς να χρησιμοποιώ τεχνικές με temporary tables, καθώς επίσης μπορώ να έχω filtering σε αυτά με ένα απλό where statement πάνω σε αυτή.

Η fn_dblog δέχεται δύο παραμέτρους τις @start και @end οι οποίες στην ουσία είναι από – έως LSN (Log Sequence Number) και σκοπό όπως είναι αυτονόητο έχουν να περιορίσουν το αποτέλεσμα στο δοσμένο διάστημα των LSNs. Φυσικά μπορείς να περάσεις την τιμή null και στις δύο εφόσον θέλεις να δεις όλο το Transaction Log.

Στην περίπτωση που θέλεις να δεις το Transaction Log πχ της AdventureWorks2008R2 μπορείς σε ένα query window να δώσεις τα παρακάτω

use AdventureWorks2008R2
go

select * from fn_dblog(null,null)
go

Το αποτέλεσμα που θα πάρεις είναι τεράστιο (117 πεδία) και δεν μπορεί να απεικονισθεί ολόκληρο αλλά ένα μικρό δείγμα από αυτό φαίνεται στην παρακάτω εικόνα

clip_image002

Η χρησιμότητα της συγκεκριμένης function είναι σημαντική καθώς μπορείς να βρεις αν πχ ένα transaction σου είναι μέσα στο backup σου ή να μάθεις πως δουλεύει το checkpoint και πολλά ακόμα…

Δεν θα ασχοληθώ με αυτά καθώς μπορείτε εύκολα να τα βρείτε στο web με μια απλή αναζήτηση.

Το πρόβλημα

Θα ασχοληθώ όμως με κάτι το οποίο αντιμετώπισα όταν άρχισα να χρησιμοποιώ την εν λόγο function και αυτό αφορά το πώς θα την χρησιμοποιήσω με συγκεκριμένες τιμές στις παραμέτρους που δέχεται.

Όπως ανάφερα παραπάνω η συγκεκριμένη function παίρνει δύο παραμέτρους οι οποίες σου δίνουν την δυνατότητα να περιορίσεις το αποτέλεσμα σου μεταξύ δύο διαφορετικών LSNs (από – έως LSN).

Βλέποντας το αποτέλεσμα που επιστρέφεται από αυτή στην κολώνα Current LSN, η οποία στην ουσία είναι και αυτή που φιλτράρεται, θα υποθέσει κανείς ότι με τον ίδιο τρόπο θα περάσω και τις τιμές σε αυτές. Αμ δεν είναι έτσι…

Τι είναι το LSN;

Για να μπορέσω να δώσω την λύση σε αυτό το πρόβλημα επιστράτευσα τις γνώσεις μου στην ανάγνωση αυτού του «περίεργου αριθμού» που ονομάζεται LSN και τις οποίες πρέπει να μοιραστώ μαζί σας ώστε να γίνει κατανοητή η λύση του.

Ξεκινώντας θα πρέπει να καταλάβουμε τι είναι το LSN και καλύτερος τρόπος για να μάθουμε για αυτό δεν είναι άλλος από τα BOL όπου στο link αυτό υπάρχει η ερμηνεία του.

«Every record in the SQL Server transaction log is uniquely identified by a log sequence number (LSN). LSNs are ordered such that if LSN2 is greater than LSN1, the change described by the log record referred to by LSN2 occurred after the change described by the log record LSN.

The LSN of a log record at which a significant event occurred can be useful for constructing correct restore sequences. Because LSNs are ordered, they can be compared for equality and inequality (that is, <, >, =, <=, >=). Such comparisons are useful when constructing restore sequences.»

Επίσης εκεί υπάρχει μια αρκετά σημαντική σημείωση

«LSNs are values of data type numeric(25,0). Arithmetic operations (for example, addition or subtraction) are not meaningful and must not be used with LSNs. »

Έχοντας αυτό σαν βασική γνώση που όμως δεν φτάνει καθώς θα πρέπει να γνωρίζουμε το Transaction Log Physical Architecture είμαστε σε θέση να μπορούμε αρχικά να διαβάζουμε και να εξηγούμε – κατανοούμε αυτόν τον «περίεργο αριθμό».

Τα τρία μέρη του LSN

Όπως έχετε δει ο αριθμός αυτός χωρίζεται σε τρία μέρη:

  • Το πρώτο μέρος δείχνει το sequence number του Virtual Log File (VLF).
  • Το δεύτερο μέρος δείχνει το offset του log block.
  • Το τρίτο μέρος δείχνει τον αριθμό του slot μέσα στο log block.

Έτσι αν πάρουμε από την παραπάνω εκτέλεση της function το πρώτο LSN που είναι ο 00000030:00000084:0001 και το μεταφράσουμε θα δούμε ότι

  • Το VLF sequence number είναι το 00000030 ήτοι 0x30 ήτοι 48 στο δεκαδικό
  • Το log block offset είναι το 00000084 ήτοι 0x84 ήτοι 132 στο δεκαδικό
  • Το slot number είναι το 1

Εκτελώντας την DBCC LOGINFO παίρνουμε το παρακάτω αποτέλεσμα

clip_image003

Από το VLF sequence number μαθαίνουμε ότι είναι το 3o VLF (FSeqNo=48) το οποίο μάλιστα είναι ενεργό (Status=2), αρχίζει από το offset 925696 και το μέγεθος του είναι 458752.

Επιβεβαιώνοντας πλέον το LSN μπορούμε να περάσουμε σωστά τις παραμέτρους στην fn_dblog.

H λύση

Έτσι το 00000030:00000084:0001 γίνεται 48:132:1 και αν πχ θέλουμε να διαβάζουμε μέχρι εκεί αρκεί να δώσουμε το παρακάτω query

SELECT * FROM fn_dblog(null,N'48:132:1')

Και το αποτέλεσμα μας θα είναι αυτό που ζητήσαμε !!!

clip_image005

Keep Rocking with SQL Server

/*antonch*/

Ημερομηνία: 01 February 2012 02:19
Αξιολόγηση:
Κατηγορίες:
Tags:
Share it:

Σχετικά Blog Post

Αφήστε το σχόλιο σας - Leave your comment

Τα σχόλια έχουν κλείσει.
Επιτρέπονται μόνο τα σχόλια από τα μέλη του SqlSchool.gr.


newsletter subscription

Εάν επιθυμείτε να λαμβάνετε ενημέρωση από εμάς, δώστε μας το e-mail σας.
PASS chapter logo
Official Professional Association for SQL Server (PASS) chapter for Greece
Join to PASS