sqlschool.gr logo

articles

Articles of SQLschool.gr Team

How can I find who consumed tempdb on a SQL Server instance

Antonios Chatzipavlis
Friday 13 June 2014

Δεν είναι λίγες οι φορές που σαν DBA θα έρθεις αντιμέτωπος με το φαινόμενο η tempdb να μεγαλώνει υπέρμετρα και ξαφνικά, ενώ δεν έχεις κάνει κάποιες αλλαγές ή δεν έχει βάλει κάτι να εκτελεστεί που είναι γνωστό ότι κάνει εκτεταμένη χρήση αυτής. Για να δούμε μπορούμε να βρούμε τι έχει γίνει;

Η ερώτηση

Αφορμή για αυτό το post είναι και πάλι μια ερώτηση που μου ήρθε από ένα συνάδελφο.

"Έχω ένα ERP από την εταιρεία Χ που έχει τα δεδομένα του σε SQL Server και η βάση είναι στα 50GB. H tempdb έχει φτάσει τα 55GB και ρωτάω την εταιρεία Χ και μου λένε κάτι κουφά όπως την tempdb την μεγαλώνει κάποιο query αλλά δεν ξέρουν ποιο είναι. Αυτή είναι η μόνη database στον SQL Server. Είναι φυσιολογικό να έχει φτάσει τόσο η tempdb;  Γιατί σε άλλο SQL Server instance έχω μεγαλύτερη βάση αλλά η tempdb είναι 5GB. Έχεις κάποιον μπούσουλα για να βρω τι είναι αυτό που χρησιμοποιεί τόσο πολύ την tempdb γιατί όπως σου είπα από την Χ εταιρεία δεν … Και πως μπορώ να μειώσω το μέγεθος της tempdb;"

Η απάντηση

Αρχικά θα πρέπει να υπενθυμίσω ότι η χρήση της συγκεκριμένη βάσης στον SQL Server με την πάροδο των εκδόσεων γίνεται όλο και μεγαλύτερη όπως έχω γράψει και σε παλαιότερο μου post (http://www.sqlschool.gr/blog/λίγα-λόγια-για-την-tempdb-στο-sql-server-2005-89.aspx) και το οποίο ακόμα και σήμερα ισχύει

Πως μειώνω το μέγεθος της tempdb;

Η απάντηση στο ερώτημα το πώς μειώνεται το μέγεθος της είναι απλή. Κάθε φορά που ξεκινάει το SQL Service η tempdb δημιουργείται με ότι έχει ορισθεί σαν αρχικό μέγεθος δημιουργίας και αυτό μπορεί κανείς εύκολα να το δει από τα properties > Files στην συγκεκριμένη βάση. Βέβαια αυτό σημαίνει ότι θα πρέπει να κάνεις ένα restart σε κάποια στιγμή που δεν γίνεται χρήση του SQL Server, αλλά θεωρώ ότι σε περιπτώσεις σαν και αυτή του συναδέλφου είναι αρκετά εύκολο να βρεθεί η στιγμή αυτή που μπορεί το σύστημα να πέσει για μερικά λεπτά.

Τι είναι αυτό που χρησιμοποιεί τόσο πολύ την tempdb;

Για να αρχίσει κανείς να απαντά στο ερώτημα του τι είναι αυτό που κάνει μεγάλη χρήση στην tempdb, θα πρέπει να δει ποια είναι η κατηγορία εργασιών που κάνει μεγάλη χρήση αυτής. Υπάρχουν τρεις κατηγορίες  βασικές κατηγορίες δραστηριοτήτων που μας ενδιαφέρουν και αφορούν τα internal objects, τα user objects και όσοι έχουν snapshot isolation level ενεργοποιημένο στην βάση τους (δείτε το SQL Night με θέμα Concurrency in SQL Server) το version store.

Αυτό μπορεί κανείς να το δει εύκολα κάνοντας ένα query στο dmv sys.dm_db_file_space_used. Αυτό επιστρέφει τόσες γραμμές όσα είναι τα data file της tempdb. Επειδή μπορεί να έχω περισσότερα από ένα συνήθως κάνω sum στα δεδομένα του για να πάρω την συνολική εικόνα. Να επισημανθεί ότι αυτό τo dmv απεικονίζει την χρονική στιγμή που εκτελείται.
Για αυτούς που πιθανώς αντιμετωπίζουν θέμα για να γράψουν το συγκεκριμένο query είναι το παρακάτω με τις επιστρεφόμενες τιμές να είναι σε ΚΒ. Αν θέλει κάποιος αυτές να είναι σε ΜΒ ας χρησιμοποιήσει την δεύτερη εκδοχή.

USE tempdb;
-- results in kb
SELECT
        SUM (user_object_reserved_page_count)*8 as [User Objects Total (KB)]
      , SUM (internal_object_reserved_page_count)*8 as [Internal Objects Total (KB)]
      , SUM (version_store_reserved_page_count)*8  as [Version Store Total (KB)]
      , SUM (unallocated_extent_page_count)*8 as [Free Space Total (KB)]
      , SUM (mixed_extent_page_count)*8 as [Mixed Extents Total (KB)]
FROM sys.dm_db_file_space_usage;
GO
-- results in mb
SELECT
        (SUM (user_object_reserved_page_count)*8)/1024.0 as [User Objects Total (MB)]
      , (SUM (internal_object_reserved_page_count)*8)/1024.0 as [Internal Objects Total (MB)]
      , (SUM (version_store_reserved_page_count)*8)/1024.0  as [Version Store Total (MB)]
      , (SUM (unallocated_extent_page_count)*8)/1024.0 as [Free Space Total (MB)]
      , (SUM (mixed_extent_page_count)*8)/1024.0 as [Mixed Extents Total (MB)]
FROM sys.dm_db_file_space_usage;
GO

Αυτό που μας ενδιαφέρει είναι να δούμε ποιο από τα User Objects Total, Internal Object Total και Version Store Total είναι μεγαλύτερο.

Εάν το μεγαλύτερο είναι το Version Store Total σημαίνει ότι μεγαλώνει το version store γρηγορότερα από ότι καθαρίζει και για αυτό θα πρέπει να δεις τι γίνεται στην βάση που έχεις ενεργοποιημένο το snapshot isolation level.

Για το internal δεν κάνουμε κάτι, και συνήθως δεν θα είναι αυτό το μεγαλύτερο. Αν είναι θα είναι στιγμιαίο και σε επόμενη εκτέλεση θα έχει μικρύνει.

Αν όμως το User Object Total είναι το μεγαλύτερο τότε κάπου υπάρχει κάτι (query) που χρησιμοποιεί temp table / variable ή αν θα δεις το execution plan θα δεις ότι περιέχει για παράδειγμα sort ή hash match ή spool operator κ.α. που  παραδοσιακά κάνουν χρήση της tempdb.

Για να δεις λοιπόν τι γίνεται εκτελείται την χρονική στιγμή αυτή και πόσο χώρο καταλαμβάνει αρκεί να εκτελεστει το παρακάτω query. Αυτό έχει σαν βάση ένα άλλο dmv το sys.dm_db_task_space_usage το οποίο επιστρέφει τις σελίδες που χρησιμοποιούνται ή ελευθερώνονται σε κάθε ενέργεια (request_id) από κάθε session(session_id) στην tempdb database (database_id=2) μαζί με το execution context (exec_context_id). Αυτά μου είναι χρήσιμα καθώς μπορώ να διαβάσω περισσότερες και χρήσιμες πληροφορίες από τα dmv που αναφέρονται στο query και μπορείτε να δείτε περισσότερες πληροφορίες για αυτά στα BOL. Φυσικά μπορείς να εμφανίσεις περισσότερη πληροφορία καθώς ο συνδυασμός αυτών των DMVs μπορεί να δώσει πολλά περισσότερα.

USE tempdb;
SELECT  
(        T.user_objects_alloc_page_count - T.user_objects_dealloc_page_count) +
        (T.internal_objects_alloc_page_count - T.internal_objects_dealloc_page_count) as [Total OutStanding Pages]   
      , (T.user_objects_alloc_page_count - T.user_objects_dealloc_page_count) as [User Objects OutStanding Pages]
      , (T.internal_objects_alloc_page_count - T.internal_objects_dealloc_page_count) as [Internal Objects OutStanding Pages]
      , T.user_objects_alloc_page_count as [User Object Allocated Pages]
      , T.internal_objects_alloc_page_count as [Internal Objects Allocated Pages]
      , T.user_objects_dealloc_page_count as [User Objects Deallocated Pages]
      , T.internal_objects_dealloc_page_count as [Internal Objects Deallocated Pages]
      , T.session_id as [session ID]
      , S.login_name as [User login]
      , S.program_name as [Application name]
      , R.start_time as [Start Time]
      , R.command as [Command Type]
      , DB_NAME(R.database_id) as [Database Name]
      , SUBSTRING(Q.text, R.statement_start_offset/2 + 1, 
                    (CASE 
                        WHEN R.statement_end_offset = -1 THEN LEN(CONVERT(nvarchar(max),Q.text)) * 2 
                        ELSE R.statement_end_offset 
                        END - R.statement_start_offset)/2) as [Query Text]
      , R.status as [Status]
      , Q.dbid as QueryExecContextDBID
      , DB_NAME(Q.dbid) as QueryExecContextDBNAME
      , Q.objectid as [Module Object Id]
      , R.cpu_time as [CPU Time (ms)]
      , R.total_elapsed_time as [Elapsed Time (ms)]
      , R.reads
      , R.writes
      , R.logical_reads
FROM sys.dm_db_task_space_usage as T 
      inner join sys.dm_exec_requests as R ON ( T.session_id = R.session_id and T.request_id = R.request_id) 
      inner join sys.dm_exec_sessions as S ON ( T.session_id = S.session_id ) 
      CROSS APPLY sys.dm_exec_sql_text(R.sql_handle) as Q
WHERE (T.internal_objects_alloc_page_count+T.user_objects_alloc_page_count) > 0
ORDER BY 1 DESC;
GO

Το συγκεριμένο query επιστρέφει αυτά τα task που έχουν το άθροισμα των allocated internal και user objects μεγαλύτερο από μηδέν, ταξινομημένα σε φθίνουσα σειρά με βάση το άθροισμα των Total OutStanding Pages.

Enjoy it
/*antonch*/

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.

Tip

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.

Connect

Explore

Learn


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.