TempDB veritabanı
TempDb geçici işlemlerin tutulduğu bir sistem veritabanıdır. Diğer sistem veri tabanlarına nispeten daha kritik bir konumdadır. Genel olarak şunları barındırır:
- Geçici tablolar (temp tables) ve bu tablolara ait veriler
- İstatistik güncellemeleri (Statistics updates)
- Trigger’lar
- Online index işlemleri (sort_in_tempdb)
- Cursor’lar
- Geçici değişkenler
- DBCC CheckDb komutu operasyonları
- Join işlemleri
SQL Server servisini yeniden başlattığımızda TempDB tekrar drop edilip oluşturulur. Diğer veritabanları gibi sürekli değildir. Servis her başladığında Model veritabanından kopyalanarak oluşturulur. TempDB’nin yedeği alınamaz, yedekten geri dönülemez ve recovery modeli değiştirilemez. Simple modeldedir. Drop edilemez. Filegroup sayısı artırılamaz. Collation bilgisi değiştirilemez. Offline ya da read only mode’a alınamaz. Yukarıda sıraladığımız içeriğinden dolayı, sorgu performansını direkt etkileyen bir sistem veritabanıdır.
TempDb’de bir geçici tablo oluşturduğumuzda, normal veritabanında tablo oluşturduğumuzda nasıl yer ayrılıyorsa (allocation), tempdb de de öyle bir allocation süreci işler. Bu süreçte üç page sözkonusudur. PFS(Page Free Space) , GAM(Global Allocation Map), SGAM(Shared Global Allocation Map). Bir sql server objesini oluşturmak ya da silmek için Sql server PFS ve SGAM page’lerine yazar. Latch dediğimiz, aşağıda açıkladığımız yapılar bu page’leri hafızada korur. Her bir tempdb data file için birer adet PFS ve SGAM page mevcuttur.
PFS(Page Free Space) : Her page için bir byte’lık bir bilgi tutar. Bu bilgi , ilgili page de ne kadar boş alan olduğunu, ne için kullanıldığını tutar. Bir PFS page yaklaşık 64MB boyutunda page’e dair bilgileri tutar. Bir data file içerisinde her 64MB için bir PFS page den söz edebiliriz. Herhangi bir veritabanı data file için ilk page PFS dir. Page ile ilgili bir veritabanı hatasında bunu görebiliriz. Örneğin 2:1:1 ifadesi, database id:2 ve 1 numaralı page demektir. Keza tempdb içn şu ifade 5:3:1 database id : 5, file id:3 ve ilk PFS page i göstermektedir.
GAM (Global Allocation Map) : GAM Page her extent (8 page), hangisinin dolu hangisinin boş olduğunu gösteren bir bitlik bir bilgi tutar. SQL Server boş extent’leri bu page’lere bakarak tespit eder. Her extent için bir bit kullanılması bir GAM page’in 4GB bir alanı yönetmesine olanak tanır. Bir data file’daki ilk GAM page’in page numarası 2’dir. 2:1:2 TempDB deki ilk GAM page’i gösterir.
SGAM (Shared Global Allocation Map) : Her extent için yine bir bit olarak mixed extent mi full extent mi bilgisini tutar. SQL server küçük verileri yerleştirmek için boş alan içeren mixed extentleri bulmak için bu page’i kullanır. GAM gibi 4GB lık bir alanı yönetir. Bir data file daki ilk SGAM page’in numarası 3 tür. Yani 2:1:3 tempdb nin ilk SGAM page’idir.
Latch Kavramı
Buffer pool, işletim sisteminin SQL server için hafızada(memory) rezerve ettiği bir alandır. SQL Server gelen taleplere göre diskten ilgili page’leri memory de buffer pool’a atar. Bu sistem içerisinde, verinin buffer pool içerisinde tutarlılığını korumak için bir sisteme ihtiyaç vardır. Latch, SQL Server’ın memory içindeki bu verinin tutarlılığını sağladığı bir lock mekanizmasıdır. Paylaşılan hafıza haynaklarını korumaya yarar. Bir thread bir page üzerinde çalışmayı talep ettiğinde, aynı anda bir page’i sadece bir thread değiştirebileceğinden bu latch üzerinde “latch queue” denilen kuyruk oluşur. Bu page taleplerini dağıtmak amacıyla tempdb data file sayısının , işlemci çekirdek sayısıyla orantılı olarak artırılması önerilir. Çünkü her bir data file için ayrı bir “latch queue” vardır. Bu data file sayısını artırma işlemi thread’in page’i bekleme süresini azaltır. Bu da sorgu performansının artması demektir. Aşağıda bu konuyu resmetmeye çalıştım.
TempdDB Metadata Contention
Birden fazla session geçici tablo oluşturduğu esnada, TempDB’nin sistem tablolarına aynı anda erişmek istediğinde metadata contention oluşur. Bu iş yükü sistem tablolarında gecikmeye sebep olur ve sorgu performansları düşmeye başlar.
TempDb yapılandırması için öneriler:
- Antivirüs taramasından SQL Server dosyalarını exclude etmek
- TempDB yi ayrı bir diskte ve mümkünse SSD üzerinde tutmak. Data ve Log dosyalarını ayrı diskte tutmak.
- Raid0 ya da Raid10 yapısında tutmak.
- TempDB yi başka uygulamaların, veritabanlarını kullandığı disklerde konumlandırmamak
- Index Rebuild işleminde “sort in tempdb” seçeneği tempdb performansını etkiler. Gereksiz kullanımından kaçınılmalıdır.
- Sec/Read ve Avg. Sec/Write oranını takip edip 50ms altında kalmasına dikkat etmek
- Şu wait türleri TempDb performansıyla doğrudan ilişkilidir. PAGELATCH_EX, PAGELATCH_UP, CXPACKET
- TempDb contention durumunu takip etmek. Microsoft’un “allocation contention” problemini azaltmak için önerilerine şu yazıdan ulaşabilirsiniz.
- TempDB data file sayısını, sisteminiz 8 core dan az ise core sayınız kadar, 8 core dan fazla ise 8 data file olarak ayarlamak. Data file boyutlarının aynı olması önemlidir. İşlemci sayısının 8 den fazla olduğu durumda 8 den fazla her 4 core için bir data file eklenebileceğini söyleyenler de vardır. Onlarca core içeren sunucular için bu düşünülebilir. Yani 12 core varsa 8 + 1 (kalan 4 core için bir file) = 9. Düşük ölçekli sunucularda daha önceleri 8 core için 8 dosya uygundu. Ancak onlarca core içeren sistemler için yük testi yaparak 8 den fazla dosya sayısına karar vermek daha yerindedir.
- Autogrowth özelliği açık olmalı. Tempdb her otomatik büyüme esnasında “exclusive lock” mekanizmasıyla kilitlenir. Bu da performansı doğrudan kötü etkiler. Veritabanı kurulurken en uygun başlangıç boyutunu (en az 2048 MB gibi) ve auto growth boyutunu vermek bu yüzden çok önemlidir.
TempDB nin sistem üzerinde tutulduğu yer bilgisi için sp_helpdb tempdb komutu kullanılabilir.
TempDb’nin kullandığı disk alanını sys.dm_db_file_space_usage DMV’sini sorgulayarak görebiliriz. Tempdb içerisinde çok fazla yer kaplayan nesneleri görmek için ise sys.dm_db_session_space_usage ve sys.dm_db_task_space_usage dmv’leri kullanılabilir.