sqlschool.gr logo


Articles of SQLschool.gr Team

About LSNs in SQL Server

Antonios Chatzipavlis
Thursday 04 January 2018

Πολλά πράγματα μέσα στον SQL Server γίνονται με βάση το LSN (Log Sequence Number). Αρκετές πάλι είναι οι ερωτήσεις που δέχομαι για αυτό και κυρίως αφορούν πως αυτό μεταφράζεται. Μέσα από αυτό το άρθρο θα προσπαθήσω να το εξηγήσω όσο καλύτερα και ευκολότερα γίνεται.

Αρχικά θα πρέπει να αναφερθεί αυτούσιο αυτό που τα BOL γράφουν σχετικά με το LSN

"Every record in the SQL Server transaction log is uniquely identified by a log sequence number (LSN). 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"

Αυτό σημαίνει ότι υπάρχει συνεχόμενη αύξουσα σειρά το οποίο σημαίνει ότι το μεγαλύτερο μεταξύ δυο LSNs είναι και το πρόσφατο.

Επίσης θα πρέπει να επισημανθεί ότι συναντάμε το LSN σε αρκετά σημεία μέσα στο SQL Server ιδιαίτερα στα backups αλλά και σε metadata DMVs που αφορούν πληροφορίες σχετικά με την εκάστοτε database.

Σε αυτά όλα τα σημεία συναντάμε το LSN σε δύο μορφές.

Η μία είναι στην μορφή ΧΧΧΧΧΧΧΧ:ΧΧΧΧΧΧΧΧ:ΧΧΧΧ και η άλλη σαν αριθμό.

Στην πρώτη μορφή όπως φαίνεται υπάρχουν τρία τμήματα τα οποία χωρίζονται με το χαρακτήρα column (:) και το πρώτο και δεύτερο είναι 8 χαρακτήρες και το τρίτο 4 χαρακτήρες και οι τιμές σε αυτά είναι σε HEX (δεκαεξαδικό).

Το πρώτο από αυτά είναι ο αριθμός του Virtual Log File (VLF) στο οποίο βρίσκεται το συγκεκριμένο log record.

To δεύτερο είναι το offset από το οποίο ξεκινάει το συγκεκριμένο log record μέσα στο VLF.

Το τρίτο είναι ο slot number μέσα στο VLF στο οποίο υπάρχει το log record.

(Μπορείτε να δείτε τα σχετικά μου άρθρα & videos στο SQLschool.gr σχετικά με τα VLFs εύκολα με μια απλή αναζήτηση με το keyword VLF)

Επειδή όπως είπα και παραπάνω οι τιμές είναι σε HEX αλλά στο SQL Server δεν υπάρχει function που να κάνει convert σε δεκαδικό χρησιμοποιούμε την convert function στην οποία στην τιμή του κάθε τμήματος προσθέτουμε το '0x' και αυτό το κάνουμε varbinary με style=1 στο αντίστοιχο όρισμα της convert πχ convert(varbinary,'0x'+left ([current lsn],8),1).

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

Για το ανάποδο θα πρέπει να ακολουθηθεί η αντίστροφη διαδικασία.

Μια όμως παρατήρηση έχω για να σας προλάβω και να μην έχετε προβλήματα.

Όπως θα δείτε χρησιμοποιώ την fn_dblog function με την οποία μπορεί κάποιος να διαβάσει τα περιεχόμενα του log σε μια database. Αυτό το κάνω σε ένα περιβάλλον που είναι για lab. Φυσικά και μπορείτε να το κάνετε και σε παραγωγικό περιβάλλον απλά πρέπει να ξέρετε ότι η συγκεκριμένη function μπορεί να πάρει αρκετή ώρα μέχρι να φέρει αποτέλεσμα και όση ώρα εκτελείται δημιουργεί καθυστερήσεις.

use TSQLV4;
        [Current LSN],
        -- part 1
        left ([current lsn],8) as lsn_part1,
        convert(varbinary,'0x'+left ([current lsn],8),1) as hex_of_lsn_part1,
        cast(convert(varbinary,'0x'+left ([current lsn],8),1) as int ) as int_of_lsn_part1_is_vlf_id,
        -- part 2
        substring([current lsn],10,8) as lsn_part2,
        convert(varbinary,'0x'+substring([current lsn],10,8),1) as hex_of_lsn_part2,
        cast(convert(varbinary,'0x'+substring([current lsn],10,8),1) as int) as int_of_lsn_part2_is_offset_in_log_block,
        -- part 3
        RIGHT([current lsn],4) as lsn_part3,
        convert(varbinary,'0x'+RIGHT([current lsn],4),1) as hex_of_lsn_part3,
        cast(convert(varbinary,'0x'+RIGHT([current lsn],4),1) as int) as int_of_lsn_part3_is_slot_num_inlog_block,
        -- lsn as a number 
        cast (right('00000000'+cast(cast(convert(varbinary,'0x'+left ([current lsn],8),1) as int ) as varchar(8)),8)+
        right('00000000'+cast(cast(convert(varbinary,'0x'+substring([current lsn],10,8),1) as int) as varchar(8)),8)+
        right('00000'+cast(cast(convert(varbinary,'0x'+RIGHT([current lsn],4),1) as int) as varchar(5)),5) as bigint ) as lsn_in_number_format
from fn_dblog(null,null);


Antonios Chatzipavlis

Antonios Chatzipavlis

Antonios is a Data Solutions Consultant and Trainer. He has been working in IT since 1988. In his career, he has worked as senior developer, IT Manager, Solutions Architect and IT Consultant. Since 1995 he has been devoted on new technologies and software development tools, mainly by Microsoft, either by training company staff and colleagues or assisting them in design, development and implementation as a consultant or chief developer. He has focused in Databases and Data Science since 1995. He specialized in Microsoft SQL Server since version 6.0 in areas like SQL Server Internals, Database Design and Development, Business Intelligence and in 2010 he has started working with Azure Data Platform, NoSQL databases, Big Data Technologies and Machine Learning. He is an active member of many IT communities in Greece, answering colleagues' questions and writing articles in his web site. He is the owner of SQLschool.gr which is a community portal with a lot of information about Microsoft SQL Server. He has been a Microsoft Certified Trainer (MCT) since 2000. Microsoft honored him as MVP on Data Platform due to his activities in SQL Server since 2010. He holds a large number of Microsoft Certifications and Microsoft SQL Server Certifications since version 6.5.


What's New in SQL Server 2022 - Episodes

More Tips...

Become a member

If you want to receive updates from us become a member to our community.




sqlschool.gr © 2010-2024 All rights reserved

This site uses cookies for operational and analytics purposes only. By continuing to browse this site, you agree to their use.