Ένα ενδιαφέρον video όπως παρουσιάστηκε στην WPC11 σχετικό με το “Crescent” το οποίο έχει σχεδιαστεί όπως λέει η Microsoft
Project "Crescent" is designed with end users in mind to quickly, easily, and visually explore their data and answer ad-hoc questions in just a few clicks.
Μπορείτε να το δείτε εδώ
Όταν για πρώτη φορά εμφανίστηκε το συγκεκριμένο feature στον SQL Server 7.0 ίσως να ήμουν ο πρώτος στην Ελλάδα που το χρησιμοποίησα σε παραγωγικό περιβάλλον. Παρόλα αυτά όμως δεν υπήρχε η υποστήριξη της ελληνικής γλώσσας και αυτό με είχε στεναχωρίσει ιδιαίτερα. Αυτό σήμαινε ότι δεν μπορούσα να ψάξω με την ρίζα της λέξης. Από τότε προσπαθούσα εγώ και ακόμα ένας συνάδελφος ο Παναγιώτης ο Καναβός να πείσουμε την Microsoft να υποστηρίξει την ελληνική γλώσσα. Οι προσπάθειες μας όμως ήταν άκαρπες. Παρόλα αυτά όμως δεν το έβαλα κάτω. Από το 2010 που έγινα MVP στο SQL Server άρχισα να γίνομαι, στο μέτρο του δυνατού, τσιμπούρι στο product group ώστε να υποστηριχθεί η ελληνική γλώσσα. Κάθε λίγο και λιγάκι έστελνα emails και ζητούσα την υποστήριξη της γλώσσα μας. Το τελευταίο μου email ήταν στις 4/6/2011. Με χαρά, (πάρτυ θα κάνω) ανακοινώνω ότι στο CTP3 του Denali πλέον υπάρχει η υποστήρξη της ελληνικής. Έτσι πλέον μπορείς να ψάξεις με την ρίζα της λέξης
Προσέξτε ότι δουλεύει περίφημα καθώς κάνει ορθογραφική υλοποίηση. Αν παρατηρήσετε στην παραπάνω εικόνα θα δείτε ότι την μετοχή της λέξης που έχω γράψει λάθος στη γραμμή 6 δεν την φέρνει, ενώ στην γραμμή 9 που είναι σωστή την φέρνει. Ε Ξ Α Ι Ρ Ε Τ Ι Κ Α !!!!!!!!!!!!!!!!!!!!!! @antonch
Αρκετές φορές θέλουμε να δούμε το πως είναι configure o SQL Server με μιά ματία. Αντί να “τρέχουμε” από εδώ και από εκεί μέσα στον SSMS υπάρχει λύση, και αυτή δεν είναι άλλη από το να ανοίξουμε ένα νέo query και σε αυτό να γράψουμε
Σήμερα ένας αγαπητός φίλος και συνάδελφος μου έστειλε mail και με ρωτούσε
Αντώνη καλησπέρα,
Πως μπορώ να κάνω convert απο nvarchar se iso-8859-7 μέσω SSIS για να το κάνω export σε Flatfile?
Η απάντηση είναι η εξής Tην στιγμή που ορίζω τον connection manager στο παραγόμενο flat file όριζω στο Code Page του αρχείου την τιμή 28597 (ISO 8859-7 Greek)
Υπάρχει βέβαια η περίπτωση σε πεδία τα οποία είναι ntext ή nvarchar(max) να μου γκρινίαζει και να μου λέει ότι δεν μπορεί να τα μετατρέψει αλλά και πάλι υπάρχει λύση, βάζω ένα Data Conversion Task
στο οποίο ορίζω τα παρακάτω
και το αρχείο μου παράγεται όπως το θέλω αφού βέβαια στα mappings βάλω την νέα κολώνα
Αν και η συγκεκριμένη εντολή είναι ευρέως γνωστή και σίγουρα θα την έχετε βρει σε διάφορα sites εντούτοις θα γράψω και εγώ για αυτή καθώς θεωρώ ότι είναι μια σημαντική εντολή αν και είναι undocumented. Φυσικά μπορούμε με ασφάλεια να την χρησιμοποιήσουμε σε παραγωγικά συστήματα χωρίς φόβο και πάθος. Με αυτή μπορούμε να δούμε αναλυτικές πληροφορίες για τους indexes σε ένα συγκεκριμένο object ανά σελίδα. Η σύνταξη της εντολής είναι η παρακάτω DBCC IND ( {‘dbname’|dbid} , {‘objectname’|objectid} , {nonclustered index id | 0 | 1 | -1 | -2 } [, partition number] )
Υποχρεωτικές είναι οι πρώτες τρεις παράμετροι, αναλυτικά
{‘dbname’|dbid}
Σε αυτή δίνουμε είτε το όνομα της βάσης είτε το dbid αυτής το οποίο μπορούμε να πάρουμε είτε κάνοντας ερώτημα στο sys.databases είτε χρησιμοποιώντας την db_id metadata function του SQL Server.
{‘objectname’|objectid}
Σε αυτή δίνουμε τον πίνακα ή το indexed view για το οποίο θέλουμε να δούμε τον/τους indexes του. Αυτό γίνεται είτε δίνοντας το όνομα του είτε χρησιμοποιώντας τη object_id metadata function.
{nonclustered index id | 1 | 0 | -1 | -2 }
Σε αυτή δίνουμε το index id ενός nonclustered index (το εύρος των τιμών είναι από 2-250 και 256-1005) και παίρνουμε πληροφορίες για όλες τις IAM, data pages, indexes pages ενός index ή μία από τις παρακάτω τιμές
0
Δίνοντας αυτή την τιμή παίρνουμε πληροφορίες για τα in-row data pages και IAM pages in-row και σε αυτές, φυσικά για το object το οποίο έχουμε ορίσει παραπάνω.
1
Δίνοντας αυτή την τιμή παίρνουμε πληροφορίες που αφορούν όλα τα pages (IAM, data pages, LOB pages/row overflow pages), αν στο object που έχουμε δώσει υπάρχει clustered index συμπεριλαμβάνεται.
-1
Δίνοντας αυτή την τιμή παίρνουμε πληροφορίες για ΟΛΟΥΣ τους indexes που υπάρχουν στο object που διερευνούμε.
-2
Δίνοντας αυτή την τιμή παίρνουμε πληροφορίες για όλες τις ΙΑΜ που υπάρχουν στο συγκεκριμένο object.
Το αποτέλεσμα το οποίο επιστρέφεται από την εκτέλεση της εντολής περιέχει τα παρακάτω στοιχεία
PageFID
Το File ID στο οποίο ανήκει η σελίδα
PagePID
Ο αριθμός της σελίδας στο αρχείο (FileID)
IAMFID
Το file id στο οποίο η ΙΑΜ υπάρχει
IAMPID
Ο αριθμός της σελίδας στο αρχείο
ObjectID
Το object ID
IndexID
O αριθμός του index (0-250 & 256-1005)
PartitionNumber
To partition number
PartitionID
To partition ID
IAM_Chain_Type
Ο τύπος του allocation στην σελίδα (in-row, row-overflow, LOB)
PageType
1=data page, 2=index page, 3= text mixed page, 4 = text tree page, 10 = IAM
IndexLevel
0= leaf level , 1,2,3… = τα παραπάνω levels
NextPageFID
Το File ID που περιέχει την επόμενη σελίδα του συγκεκριμένου level
NextPagePID
Το αρχείο που περιέχει την επόμενη σελίδα του συγκεκριμένου level
PrevPageFID
Το File ID που περιέχει την προηγούμενη σελίδα του συγκεκριμένου level
PrevPagePID
Το αρχείο που περιέχει την προηγούμενη σελίδα του συγκεκριμένου level
Αν και έχω αρκετό καιρό να διοργανώσω ένα SQL Saturday Night, θα ήθελα να σας ενημερώσω ότι αυτά δεν σταμάτησαν όπως ακούστηκε. Η αλήθεια είναι ότι σταμάτησαν κάπως απότομα αλλά έπεσε αρκετή δουλεία που δεν είχα την ευκαιρία να προετοιμαστώ για νέο. Κάποια στιγμή σκέφτηκα να κάνω ένα προς το τέλος του επόμενου μήνα όπου κάπως ξαλαφρώνω από δουλειά αλλά μάλλον χαμένο θα πάει καθώς θα είναι αρκετοί σε διακοπές και είναι δύσκολο σαββατόβραδο να είναι κλεισμένος κάποιος μέσα.
Για όλους αυτούς τους λόγους αποφάσισα να ξεκινήσουμε από Σεπτέμβρη ξανά, δυναμικά και με περισσότερα θέματα τα οποία θα ετοιμάσω όλο το καλοκαίρι. Εξάλλου έχω να σας πω πολλά και για τον επόμενο SQL Server. Και τώρα έχω αλλά επειδή ακόμα δεν είναι ξεκάθαρο το τι μπορώ να μοιραστώ μαζί σας καθώς υπάρχει το NDA, δεν μπαίνω σε αυτό το ρίσκο. Μόλις το τοπίο ξεκαθαρίσει θα σας έχω πολλά ωραία πράγματα να σας πω και ίσως να έχω και καλά νέα σχετικά με ένα feature που έχει ο SQL Server σε σχέση με την Ελληνική γλώσσα. Ασκώ πιέσεις ελπίζω να τα καταφέρω.
Ακόμα θα ήθελα για μια ακόμα φορά να τονίσω το τι προσπαθώ να κάνω μέσω των SQL Saturday Nights. Αυτός δεν είναι άλλος από το φέρω τον κόσμο κοντά στο SQL Server. Δεν είναι δυνατόν σε όσα θέματα αναλύω να μπαίνω σε μεγάλο βάθος. Σκοπός μου είναι να δίνω όλα όσα χρειάζονται για να κάνετε εύκολα την δουλειάς σας. Φυσικά πάντα υπάρχει και το παρακάτω από εκεί που σταματάμε αλλά πρέπει να μπαίνει και ένα φρένο ώστε να δίνεται η δυνατότητα σε όλους να μαθαίνουν κάτι το οποίο να χρησιμοποιείται σαν σκαλοπάτι γερό ώστε να έχουμε σταθερό βήμα και όχι αυτό να τρέμει. Φυσικά καταλαβαίνω και αυτούς που θέλουν να τα μαθαίνουν όλα σε βάθος. Αλλά και αυτό είναι κάτι σχετικό.
Όπως και να έχει όμως εύχομαι σε όλους καλό καλοκαίρι , καλή ξεκούραση και ραντεβού το Σεπτέμβρη όσον αφορά τα SQL Saturday Nights, γιατί blog post θα έχουμε ;-)
Το Microsoft® SSIS Balanced Data Distributor (BDD) είναι ένα νέο SSIS transform, το οποίο παίρνει ένα single input και το κάνει distribute τα rows σε ένα ή περισσότερα outputs uniformly μέσω multithreading.
Στον SQL Server υπάρχει το option AWE (μπορεί κανείς να το αλλάξει είτε με δεξί κλικ στον όνομα του server μέσα από το SSMS Properties\Memory είτε με την χρήση της sp_configure).
Στην περίπτωση που είστε σε 64-bit system ακόμα και αν την ενεργοποιήσετε αυτή δεν λαβανετε υποψη, εκτός αν δώσετε στο SQL Server service account το Lock Pages in Memory privilage και είστε σε Enterprise Edition.
Στην αρχή ήταν μόνο για Enterprise Editon αλλά μετά από feedback Που δώθηκε στην Microsoft στον 2008 με την χρήση του SQL Server 2008 SP1 + Commulative Update 2 και την χρήση trace flag αυτό μπορεί να παίξει και στην Standard Edition. Περισσότερα
εδώ
Εάν όλα τα παραπάνω έχουν γίνει τότε στο SQL Server Error Log θα δείτε να γράφει:
Using Locked Pages for Buffer Pool
ΠΡΟΣΟΧΗ : Αυτό δεν πρέπει να χρησιμοποιείται σαν best practice σε όλους τους SQL Servers που έχουμε είναι workaround και αλλάζει μόνο εφόσον συντρέχουν οι λόγοι για να αλλάξουμε την συμπεριφορά των 64-bit
Για να κάνω monitoring το μέγεθος της buffer cache αρκεί μέσα από το Performance Monitor Tool των Windows να ορίσω τους μετρητές:
SQLServer: Memory Manager \ Total Server Memory (KB)
Δείχνει το τρέχων μέγεθος της buffer cache.
SQLServer: Memory Manager \ Target Server Memory (KB)
Δείχνει το πάνω όριο της μνήμης που έχει εκείνη την στιγμή έχει ορίσει ο SQL Server ότι μπορεί να χρησιμοποιήσει για την buffer cache. Το νούμερο αυτό μπορεί να αλλάξει δυναμικά και αυτό γίνεται στις περιπτώσεις που ο SQL Server διαπιστώσει
ότι το σύστημα είναι σε memory pressure (μειώνει την μνήμη)
ότι το σύστημα δεν είναι σε memory pressure (αυξάνει την μνήμη αλλα δεν θα γίνει μεγαλύτερη από ότι έχω ορίσει στην Max Memory)
Προσοχή. Σε καμία περίπτωση αυτοί οι μετρητές δεν δείχνουν την συνολική μνήμη του SQL Server, αλλά μόνο την μνήμη που αφορά την buffer cache.
Καθαρίζει όλα τα μη ενεργά/χρησιμοποιούμενα περιεχόμενα (cache entries) από όλες τις cache. Αν και ο SQL Server ενεργεί προκαταβολικά ώστε να γίνει αυτό, εντούτοις μπορώ χειροκίνητα να το κάνω αυτό εκτελώντας την
DBCC FREESYSTEMCACHE ('ALL')
Φυσικά το παραπάνω θα πρέπει να το κάνουμε μόνο εφόσον θέλουμε να καθαρίσουμε τα πάντα και φυσικά λαμβάνοντας υπόψη τα Remarks από τα BOL.
Καλό είναι να εστιάζουμε την προσοχή μας σε συγκεκριμένο pool και να σβήνουμε αυτό εφόσον έχουμε δει ότι μας δημιουργεί πρόβλημα το μέγεθος του. Αυτό μπορεί να γίνει με την
DBCC FREESYSTEMCACHE ('pool name')
Μπορείς να δεις τα pools που υπάρχουν εκτελώντας το
SELECT DISTINCT name FROM sys.dm_os_memory_clerks
Σε αρκετές περιπτώσεις καθαρίζοντας τα παρακάτω pools βελτιώνω αρκετά το performance.
SQL Plans : σε περίπτωση που δεν έχω κάνει optimize τον SQL Server για plan cache bloat.
TokenAndPermUserStore : εάν είμαι σε SQL Server 2005 SP2 και πίσω με την οποία καθαρίζουμε την μνήμη που έχει καταναλωθεί από την Security Cache για την δημιουργία objects στην tempdb.
Διαγράφει από την στοιχεία από την plan cache. Αυτό μπορεί να γίνει είτε για όλα τα στοιχεία, είτε για συγκεκριμένο plan, είτε για όλα όσα αφορούν συγκεκριμένο resource pool.
Πρέπει να την χρησιμοποιούμε με σύνεση καθώς μπορεί να σβήσουμε πχ το πλάνο μιας stored procedure κατά λάθος. Αυτό σημαίνει ότι την επόμενη φορά που αυτή θα ζητηθεί να εκτελεστεί αυτή θα περάσει όλα τα στάδια (Parse,Optimize....) ώστε να μπει το πλάνο της ξανά μέσα στην plan cache και να εκτελεστεί και φυσικά να επαχρησιμοποιηθεί αυτό στις επόμενες εκτελέσεις της.
Για περισσότερες πληροφορίες μπορείτε να δείτε τα BOL.
Η λατρεία μου για τα poster είναι γνωστή. Ειδικά για αυτά που αφορούν τον SQL Server. Αν μάλιστα αυτά είναι χαριτωμένα, έξυπνα και λένε πολλά μου αρέσουν περισσότερο. Γενικά είμαι poster hunter. Χθες τυχαία ανακάλυψα αυτό που ακολουθεί το οποίο το έχει φτιάξει η Kendra Little (blog|twitter) το οποίο εξηγεί αρκετά όμορφα τα SQL Server Isolations Levels. Μπορείτε να το κατεβάσετε από το original link ή και από εδώ.
Για να ορίσω το πόσο θα είναι ο χώρος που θα καταλαμβάνει η buffer cache αρκεί να ορίσω το Min και Μax Server Memory. Αυτά τα settings ορίζουν μόνο την buffer cache και όχι όλη την μνήμη που θα καταλαμβάνει ο SQL Server.
Η DBCC DROPCLEANBUFFERS καθαρίζει την buffer cache μόνο από τις σελίδες που είναι χαρακτηρισμένες ως clean. Σε καμία περίπτωση δεν πειράζει όσες είναι dirty.
Σε τακτά χρονικά διαστήματα ή σε περιπτώσεις που υπάρχει στέρηση σε μνήμη, ένα thread αναλαμβάνει να κάνει τον καθαρισμό της buffer cache από τις σελίδες που δεν έχουν πρόσφατα χρησιμοποιηθεί. Το thread αυτό ονομάζεται Lazywriter και ο τρόπος με τον οποίο αποφασίζει ποιες είναι αυτές που θα φύγουν από την buffer cache είναι και ονομάζεται Least Recently Used (LRU) policy. Least Recently Used policy Στο header της κάθε σελίδας όταν αυτή είναι στη μνήμη αποθηκεύονται πληροφορίες που κρατάνε τις τελευταίες δύο φορές (time) που αυτή έχει χρησιμοποιηθεί. Επίσης υπάρχει ένας μετρητής ο οποίος κάθε φορά που γίνεται ο περιοδικός έλεγχος (Lazywriter) αυτός μειώνεται. Έτσι στην περίπτωση που χρειάζεται να ελευθερωθεί χώρος στη buffer cache οι σελίδες με τη μικρότερη τιμή στο μετρητή είναι αυτές που φεύγουν από αυτή. Αν θέλουμε να δούμε πόσο χρόνο (μέση τιμη) οι σελίδες μένουν στην buffer cache μπορούμε να το δούμε με την χρήση του Page Life Expectancy performance counter. Lazywriter operation Είναι ένα thread το οποίο τακτικά ελέγχει το μέγεθος του free buffer list.
O SQL Server προσπαθεί να συντηρήσει ένα αριθμό από ελεύθερες σελίδες στην buffer cache με σκοπό να μπορεί να ανεβάζει σε αυτή γρηγορότερα σελίδες, αυτός ο αριθμός ελέγχεται από το free buffer list.
Όποτε γίνεται ο συγκεκριμένος έλεγχος (ή γίνεται checkpoint ή read operation που χρειάζεται να διαβάσει σελίδες από το δίσκο και να τις ανεβάσει στην buffer cache) και δει ότι ο αριθμός αυτός είναι μικρότερος από αυτό που έχει το free buffer list τότε με βάση το LRU policy οι σελίδες αυτές φεύγουν από την buffer cache.
Στην περίπτωση που μια σελίδα είναι dirty και εμπίπτει στο LRU policy τότε αυτή γράφεται στο δίσκο (data file) πριν χαρακτηριστεί σαν σελίδα που μπορεί να φύγει από την buffer cache.
Η διαδικασία αυτή όταν γίνεται μεταφέρει τις χαρακτηρισμένες ως dirty pages από την μνήμη (buffer cache) στο δίσκο (data file(s)) και αλλάζει στο header τους το status από dirty σε clean. Δεν αδείαζει-καθαρίζει την buffer cache από αυτές.
Όταν μια σελίδα διαβάζεται από τον δίσκο και μπαίνει στην buffer cache θεωρείται ότι είναι μια Clean Page. Όταν όμως κάνω ένα transaction το οποίο την επηρεάζει (πάντα στην μνήμη) αυτή είναι μια Dirty Page (μπαίνει ένα mark στον header της) καθώς η εικόνα στην μνήμη είναι διαφορετική από αυτή στο δίσκο. Για να δω πόσες dirty pages έχω ανά βάση αρκεί να εκτελέσω το παρακάτω query που χρησιμοποιεί την sys.dm_os_buffer_descriptors SELECT db_name(database_id) AS 'Database',count(page_id) AS 'Dirty Pages' FROM sys.dm_os_buffer_descriptors WHERE is_modified =1 GROUP BY db_name(database_id) ORDER BY count(page_id) DESC
Όπως γνωρίζουμε ο SQL Server διαβάζει τις σελίδες από το δίσκο και τις βάζει στην buffer cache. To πόσο χρόνο (σε δευτερόλεπτα) αυτές μπορούν να μείνουν κατά μέσο όρο στην buffer cache χωρίς να ζητηθούν/χρησιμοποιηθούν μπορούμε να το δούμε από τον SQL Server\Buffer Manager\Page Life Expectancy performance counter. O μετρητής αυτός σύμφωνα με τα recommendations πρέπει να είναι πάνω από 300 sec για να έχουμε ένα καλό PLE. Φυσικά σε σύστήματα που έχουν προβλήματα με την μνήμη αυτός θα είναι μικρότερος καθώς οι σελίδες θα κατεβαίνουν γρηγορότερα στον δίσκο και αυτό δεν μας αρέσει. Αντίθετα σε συστήματα με άπλετη μνήμη θα έχει μεγαλύτερη τιμή και αυτό μας αρέσει.
Η DMV αυτή δείχνει μια γράμμη για κάθε data page η οποία είναι στην buffer cache. Με το παρακάτω script μπορείς να δεις το ποσό σε MB που έχει δεσμευτεί από τις σελίδες που υπάρχουν για κάθε βάση μέσα στην buffer cache SELECT CASE database_id WHEN 32767 THEN 'ResourceDB' ELSE DB_NAME(database_id) END AS 'Database', COUNT(*)*8/1024 AS 'Cached Size (MB)' FROM sys.dm_os_buffer_descriptors GROUP BY DB_NAME(database_id),database_id ORDER BY 2 DESC
Καιρό ήθελα να γράψω για αυτή και όλο το ξεχνούσα. Πρόσφατα σε μια εκπαίδευση αναφέρεθηκε το όνομα της και αφού το έβαλα σε χίλια δυο σημεία να το κάνω post και να μην το ξεχάσω τελικά τα κατάφερα και δεν την ξέχασα. Αρκετές φορές θέλουμε να μεταφέρουμε τα logins που έχουμε σε ένα SQL Server σε κάποιον άλλον. Ιδιαίτερα χρήσιμη όταν έχουμε database mirroring, replication κλπ. Υπάρχει ένα άρθρο το οποίο σου δίνει τον κώδικα αυτής και φυσικά αφού την δημιουργήσεις μπορείς να την εκτελέσεις και να πάρεις στο πιάτο τα logins σε μορφή script ώστε να μπορέσεις να τα δημιουργήσεις με κάποιες παραδοχές σε κάποιον άλλον SQL Server. Για καθαρά λόγους ευκολίας σε εσάς μεταφέρω το κώδικα εδώ USE master GO IF OBJECT_ID ('sp_hexadecimal') IS NOT NULL DROP PROCEDURE sp_hexadecimal GO CREATE PROCEDURE sp_hexadecimal @binvalue varbinary(256), @hexvalue varchar (514) OUTPUT AS DECLARE @charvalue varchar (514) DECLARE @i int DECLARE @length int DECLARE @hexstring char(16) SELECT @charvalue = '0x' SELECT @i = 1 SELECT @length = DATALENGTH (@binvalue) SELECT @hexstring = '0123456789ABCDEF' WHILE (@i BEGIN DECLARE @tempint int DECLARE @firstint int DECLARE @secondint int SELECT @tempint = CONVERT(int, SUBSTRING(@binvalue,@i,1)) SELECT @firstint = FLOOR(@tempint/16) SELECT @secondint = @tempint - (@firstint*16) SELECT @charvalue = @charvalue + SUBSTRING(@hexstring, @firstint+1, 1) + SUBSTRING(@hexstring, @secondint+1, 1) SELECT @i = @i + 1 END
SELECT @hexvalue = @charvalue GO
IF OBJECT_ID ('sp_help_revlogin') IS NOT NULL DROP PROCEDURE sp_help_revlogin GO CREATE PROCEDURE sp_help_revlogin @login_name sysname = NULL AS DECLARE @name sysname DECLARE @type varchar (1) DECLARE @hasaccess int DECLARE @denylogin int DECLARE @is_disabled int DECLARE @PWD_varbinary varbinary (256) DECLARE @PWD_string varchar (514) DECLARE @SID_varbinary varbinary (85) DECLARE @SID_string varchar (514) DECLARE @tmpstr varchar (1024) DECLARE @is_policy_checked varchar (3) DECLARE @is_expiration_checked varchar (3)
DECLARE @defaultdb sysname
IF (@login_name IS NULL) DECLARE login_curs CURSOR FOR
SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM sys.server_principals p LEFT JOIN sys.syslogins l ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name 'sa' ELSE DECLARE login_curs CURSOR FOR
SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM sys.server_principals p LEFT JOIN sys.syslogins l ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name = @login_name OPEN login_curs
FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin IF (@@fetch_status = -1) BEGIN PRINT 'No login(s) found.' CLOSE login_curs DEALLOCATE login_curs RETURN -1 END SET @tmpstr = '/* sp_help_revlogin script ' PRINT @tmpstr SET @tmpstr = '** Generated ' + CONVERT (varchar, GETDATE()) + ' on ' + @@SERVERNAME + ' */' PRINT @tmpstr PRINT '' WHILE (@@fetch_status -1) BEGIN IF (@@fetch_status -2) BEGIN PRINT '' SET @tmpstr = '-- Login: ' + @name PRINT @tmpstr IF (@type IN ( 'G', 'U')) BEGIN -- NT authenticated account/group
SET @tmpstr = 'CREATE LOGIN ' + QUOTENAME( @name ) + ' FROM WINDOWS WITH DEFAULT_DATABASE = [' + @defaultdb + ]' END ELSE BEGIN -- SQL Server authentication -- obtain password and sid SET @PWD_varbinary = CAST( LOGINPROPERTY( @name, 'PasswordHash' ) AS varbinary (256) ) EXEC sp_hexadecimal @PWD_varbinary, @PWD_string OUT EXEC sp_hexadecimal @SID_varbinary,@SID_string OUT
-- obtain password policy state SELECT @is_policy_checked = CASE is_policy_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @name SELECT @is_expiration_checked = CASE is_expiration_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @name
IF ( @is_policy_checked IS NOT NULL ) BEGIN SET @tmpstr = @tmpstr + ', CHECK_POLICY = ' + @is_policy_checked END IF ( @is_expiration_checked IS NOT NULL ) BEGIN SET @tmpstr = @tmpstr + ', CHECK_EXPIRATION = ' + @is_expiration_checked END END IF (@denylogin = 1) BEGIN -- login is denied access SET @tmpstr = @tmpstr + '; DENY CONNECT SQL TO ' + QUOTENAME( @name ) END ELSE IF (@hasaccess = 0) BEGIN -- login exists but does not have access SET @tmpstr = @tmpstr + '; REVOKE CONNECT SQL TO ' + QUOTENAME( @name ) END IF (@is_disabled = 1) BEGIN -- login is disabled SET @tmpstr = @tmpstr + '; ALTER LOGIN ' + QUOTENAME( @name ) + ' DISABLE' END PRINT @tmpstr END
FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin END CLOSE login_curs DEALLOCATE login_curs RETURN 0 GO
Το αποτέλεσμα της εκτέλεσης του παραπάνω κώδικα θα σας δημιουργήσει δύο stored procedures στην master τις sp_hexadecimal και sp_help_revlogin.
Εκτελώντας την sp_help_revlogin θα έχετε ένα script με όλα τα logins του server που την τρέξατε.
Όπως είναι γνωρίζουμε στον SQL Server υπάρχει μια διαδικασία η οποία σκοπό έχει να μεταφέρει από την Buffer Cache τις αλλαγμένες σελίδες στο δίσκο, γίνεται σε όλες τις βάσεις εκτός από την tempdb (αν και αυτό δεν είναι και τόσο αλήθεια αλλά δεν θα το αναλύσουμε εδώ). Σκοπός του είναι να είναι όσο το δυνατό πιο ενημερωμένα τα data files με τις αλλαγές είναι γραμμένες στο log. Αυτό μπορεί να γίνει είτε εκτελώντας την εντολή CHECKPOINT είτε το κάνει o SQL Server αυτόματα. Το αυτόματο μπορεί να ορίστει αν το επιθυμούμε και αυτό γίνεται ορίζοντας το Recovery Interval στο SQL Server. H default τιμή είναι μηδέν που σημαίνει ότι ο SQL Server αποφασίζει για το πότε θα την κάνει αυτή την διαδικασία. Πρόσφατα άκουσα ότι αυτή αν δεν ορίσεις τιμή γίνεται κάθε 2 sec. Αυτό με έβαλε σε σκέψεις και αποφάσισα να το ψάξω ενδελεχώς. Σύμφωνα με τα BOL http://msdn.microsoft.com/en-us/library/ms189573.aspx στην παράγραφο για τα Automatic Checkpoints αναφέρει
The SQL Server Database Engine generates automatic checkpoints. The interval between automatic checkpoints is based on the amount of log space used and the time elapsed since the last checkpoint. The time interval between automatic checkpoints can be highly variable and long, if few modifications are made in the database. Automatic checkpoints can also occur frequently if lots of data is modified.
Αυτό όμως δεν μου έφτασε και άρχισα να κοιτάζω περισσότερα. Έφτασα σε ένα σημείο να ρωτήσω και ανθρώπους που τον έχουν φτιάξει (δεν αναφέρω τα ονόματα τους για μην θεωρηθεί ότι πουλάω μούρη ότι μιλάω μαζί τους). Τελικά οι ερωτήσεις μου και οι αναζητήσεις μου είχαν αποτέλεσμα και ανακάλυψα ότι μπορείς να χρησιμοποιήσεις τα trace flags 3502 και 3605 τα οποία γράφουν μέσα στο error log το κάθε πότε γίνεται checkpoint. Επίσης είναι αρκετά εύκολο να το δεις κάνοντας monitor τον Buffer Manager\Checkpoint Pages per Sec perfmon counter. Με ποιά όμως λογική γίνεται trigger η αυτόματη διαδικασία? Η απάντηση δια στόματος του Paul Randal είναι η παρακάτω
A checkpoint is triggered automatically under a variety of conditions. The most common condition is that enough transaction log has been generated that SQL Server estimates that if the server was to crash, it would take about one minute for crash recovery to complete. This is calculated based on the number of log records that have been generated since the last checkpoint and is known as the recovery interval. The next most common condition that triggers a checkpoint is when the log becomes 70% full.
Καθώς έχουν ήδη γίνει δέκα SQL Saturday Nights θα ήθελα την γνώμη σας για την ποιότητα αυτών. Θα παρακαλούσα αν θέλετε να μου πείτε όσοι τα έχετε παρακολουθήσει είτε ζωντάνα είτε μαγνητοσκοπημένα την γνώμη σας για αυτά. Αυτό μπορείτε να το κάνετε μπαίνοντας στο www.sqlschool.gr και στη δημοσκόπηση που υπάρχει εκεί να επιλέξετε την άποψη σας. Σας ευχαριστώ εκ των προτέρων antonch