Son zamanlarda bir ortamda Transaction Log yedeği alınırken yedek alma işleminin 1-2 saati bulabildiğini gözlemledim. Normal şartlar altında 2 dakikada bir yedek alınan ve yedeklerin de ortalama 10MB olduğu bir ortamdan bahsediyorum.
Sorunu incelerken Transaction Log yedek alma işleminin (BACKUP LOG ...) bir sistem işlemi tarafından (o anki "session_id"si 18 idi) bloke edildiğini gördüm. İşler gerçekten ilginçleşiyordu. O sistem işleminin ne olduğunu inceleyince Checkpoint olduğunu gördüm. Açıkçası, Checkpoint işleminin Transaction Log yedek işlemini bloke ettiğini ilk defa görüyordum.
Sorunu daha fazla inceledikçe aslında sorunun disk altyapısında olduğunu tespit ettim. Yani Transaction Log yedek alma işlemi aslında doğrudan kendi başına bir sorun değildi, başka bir sorunun sonucu oluşan bir durumdu.
Aklına "Disk altyapısındaki sorun, Checkpoint ve Transaction Log yedeği ne alaka?" diye soru gelenler için Checkpoint işlemine çok özetle deyineyim. SQL Server'da varolan kayıtlarda değişiklikler yaptığınızda veya yeni kayıtlar oluşturduğunuzda bu değişiklikler doğrudan veritabanı veri dosyalarına işlenmez, önce Transaction Log dosyasına işlenir, daha sonra da belli formüllere göre devreye giren Checkpoint ile bu değişiklikler ilgili veritabanı veri dosyalarına işlenir. Disk altyapısında performans sorunu olunca, Checkpoint ile değişikliklerin diske işlenmesi uzun sürüyordu ve bu da Transaction Log yedeklenmesi işlemini bloke ediyordu. Ben de bu sayede Checkpoint devam ediyorken Transaction Log yedek alınma işleminin sonlanamadığını, bloke olduğunu öğrenmiş oldum.
Biraz kısa bir yazı oldu, ama yine de değerli bir tecrübe olduğunu düşünerek paylaşmak istedim. Olur da bir gün Transaction Log'unun yedeğinin alınması uzun sürerse, disk altyapısının performansını da kontrol etmeyi unutmayın.
Not: Transaction Log ve veritabanı yedekleme işleminin uzun sürmesinin daha başka birçok nedeni var, ama bu yazıda belirli bir konuya değinmek istedim.
Ekrem Önsoy
Microsoft SQL Server Danışmanı
www.ekremonsoy.com
Microsoft SQL Server ve Microsoft SQL Server ile ilgili diğer uygulamalar, araçlar ve haberlerle ilgili Türkçe içeriği bu günlükte bulabilirsiniz.
Transaction Log etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Transaction Log etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
11 Temmuz 2017 Salı
5 Kasım 2014 Çarşamba
Rollback hakkında dikkat etmeniz gerekenler
Selam!
"sys.fn_dblog" Table Valued Function (TVF)'ını önceden duymuş muydunuz? Duymadıysanız da hayıflanmayın, çünkü zaten Microsoft tarafından dokümante edilmemiş bir TVF; bununla birlikte en azından benim bugüne kadar öyle veya böyle, orada veya burada sık sık karşılaştığım bir TVF.
Peki ne yapıyor bu adam? O anda bağlı bulunduğunuz veritabanının Transaction Log'undaki aktif kayıtları okuyor. Peki nedir bu aktif kayıtlar? Bunlar, henüz veritabanının veri dosyasına yazılmamış olan (en son yapılan Checkpoint'ten önceki), ama Transaction Log dosyasının içinde bulunan kayıtlardır.
Peki ben neden bu TVF'ten bahsetmek istedim? Size veritabanınızda bir işlem yaptığınızda bunun Transaction Log dosyasına temel olarak nasıl işlendiğini anlatmak istedim. Bununla birlikte en çok dikkat çekmek istediğim konu ise, bir Explicit Transaction başlatıp sonra bunu Rollback yaptığınızda (veya aynı şeyin bir Implicit Transaction'ın başına geldiğinde) neler olduğunu anlatmak istedim.
Örneğin bir tabloya yeni bir kayıt INSERT etmek istediğinizde bu işlemin Transaction Log dosyasına nasıl kaydedildiğini anlatayım. Bunun için test veritabanımda aşağıdaki gibi bir tablo oluşturuyorum:
CREATE TABLE [dbo].[tablom1](
[alan1] [tinyint] NULL
) ON [PRIMARY]
GO
Daha sonra aşağıdaki komut ile bu tabloya bir kayıt giriyorum
INSERT INTO tablom1 VALUES(6)
Daha sonra sys.fn_dblog TVF'ı ile Transaction Log dosyasını sorguluyorum. sys.fn_dblog TVF'ı iki tane parametre alır. Birincisi StartLSN, diğeri de EndLSN. Yani Log Sequence Number (LSN) başlangıcı ve bitişini tanımlayıp sorgulayabiliyorsunuz. LSN, her bir işlem için verilmiş eşsiz bir değerdir, 3 bölümden oluşur, ilgi VLF (Vitual Log File) numarası, ikincisi VLF içerisindeki blok numarası (bir VLF içerisinde birden fazla Transaction bulunabilir), üçüncüsü de işlem sıra numarasıdır.
Not: Transaction Log dosyası kendi içinde de mimari olarak Virtual Log File'lardan oluşur, bunlar da aralarında Active ve Passive olarak ayrılır.
Bu iki parametreyi NULL olarak belirterek de çalıştırabilirsiniz, ki genelde de böyle kullanılır:
SELECT * FROM sys.fn_dblog(NULL, NULL)
Eğer yukarıdaki INSERT komutunu çalıştırırsanız (ve sonrasında başka bir işlem yapmazsanız) sys.fn_dblog'u sorguladığınızda hemen yukarıdaki gibi bir sonuçla karşılaşacaksınız. Operation alanındaki değerleri tek tek açıklamak bu yazımın konusunun dışında, ama kırmızı dikdörtgen ile işaretlediğim alan içerisinde (Transaction ID'ye dikkat) işaretlediğim Implicit Transaction işlemini (INSERT işlemi için BEGIN TRAN ile Explicit Transaction oluşturmadık, fakat biz bunu yapmasak da her işlem bir Transaction'dır bu nedenle eğer biz tanımlamazsak bile işlemler Implicit Transaction ile çalıştırılır) açıklamaya çalışayım. LOP_BEGIN_ XACT ile Transaction'ımız başlatılmış olur, bununla LOP_COMMIT_XACT (veya işlem Rollback edildiyse de LOP_ABORT_XACT) arasında kalan işlemler gerçekleştirilmiş olur. Yukarıdaki örnekte LOP_BEGIN_XACT ile Transaction'ımızın başladığını, LOP_INSERT_ROWS ile INSERT işlemimizin gerçekleştiğini ve LOP_COMMIT_XACT ile de işlemimizin Commit edildiğini görebilirsiniz. Yani INSERT işlemimiz için Transaction Log dosyasında 3 adet kayıt oluşturulmuş oldu.
Peki Rollback'te ne oluyor? Hemen bunu da test edelim. Aşağıdaki komutu çalıştırıyorum ve bu şekilde Ornek adında bir Transaction'ı Explicitly oluşturmuş oluyorum. Ardından INSERT işlemimi gerçekleştiriyorum ve sonrasında da Transaction'ımı Rollback etmek için de ROLLBACK TRAN komutunu çalıştırıyorum. Sizce Transaction Log dosyasında kaç tane kayıt oluşmuş olacak?
BEGIN TRAN Ornek
INSERT INTO tablom1 VALUES(6)
INSERT INTO tablom1 VALUES(7)
INSERT INTO tablom1 VALUES(8)
ROLLBACK TRAN Oren
Sonuç aşağıdaki gibi:
SELECT * FROM sys.fn_dblog(NULL, NULL)
Lütfen yine kırmızı dikdörtgen ile işaretlediğim Transaction'a bakın. Yine dikkatinizi Transaction ID'ye çekmek istiyorum öncelikle, 0000:0000075d. Gördüğünüz gibi tüm INSERT ve DELETE işlemleri tek bir Transaction içerisinde gerçekleşiyor ve EVET, doğru görüyorsunuz, her bir INSERT işleminizin Rollback edilmesi için işlem başına bir LOG_DELETE_ROWS işlemi yapılıyor. En son işlem de LOP_ABORT_XACT işlemi.
Belki UPDATE için durumun ne olacağını merak ediyor olabilirsiniz, örneğin 100 kayıtlık bir UPDATE işleminiz Rollback olduğunda ne mi oluyor? Tablomuzda 100 adet kayıt varken aşağıdaki komutu çalıştırdığımızda:
UPDATE tablom1 SET alan1 = 0
ve sys.fn_dblog ile sorguladığımızda Transaction için yapılan kayıt haricinde 100 adet LOP_MODIFY_ROW işlemi görüyoruz. Rollback işleminde de tüm bu kayıtlara yine 100 adet kayıt ekleniyor!
Bu nedenlerle, özellikle uzun süren DML işlemleriniz sonucu siz elle veya kendiliğinden (bir hata sonrası) Rollback işlemi gerçekleştiğinde Transaction Log dosyanızın bulunduğu diskte yeterli derecede boş alan olduğundan emin olmanızda fayda var. Örneğin çok büyük bir işlem gerçekleştirdiniz diyelim ve bu işlem herhangi bir nedenden dolayı Rollback oldu diyelim ve tüm bunların neticesinde de Transaction Log dosyanız doldu ve hatta bulunduğu diski de doldurdu diyelim, ne mi olur? Veritabanınız Suspect duruma düşer! Ve bunun olmasını kesinlikle istemezsiniz. Bu nedenle Rollback işlemlerini özellikle kontrollü bir şekilde yapacağınız zaman bu paylaştığım bilgileri aklınızda tutun, gerekli önlemleri alın, özellikle Transaction Log dosyanızın doluluk oranını, disk doluluk oranlarını iyi ve güvenli bir şekilde takip ettiğinizden emin olun.
Sevgiler,
Ekrem Önsoy
"sys.fn_dblog" Table Valued Function (TVF)'ını önceden duymuş muydunuz? Duymadıysanız da hayıflanmayın, çünkü zaten Microsoft tarafından dokümante edilmemiş bir TVF; bununla birlikte en azından benim bugüne kadar öyle veya böyle, orada veya burada sık sık karşılaştığım bir TVF.
Peki ne yapıyor bu adam? O anda bağlı bulunduğunuz veritabanının Transaction Log'undaki aktif kayıtları okuyor. Peki nedir bu aktif kayıtlar? Bunlar, henüz veritabanının veri dosyasına yazılmamış olan (en son yapılan Checkpoint'ten önceki), ama Transaction Log dosyasının içinde bulunan kayıtlardır.
Peki ben neden bu TVF'ten bahsetmek istedim? Size veritabanınızda bir işlem yaptığınızda bunun Transaction Log dosyasına temel olarak nasıl işlendiğini anlatmak istedim. Bununla birlikte en çok dikkat çekmek istediğim konu ise, bir Explicit Transaction başlatıp sonra bunu Rollback yaptığınızda (veya aynı şeyin bir Implicit Transaction'ın başına geldiğinde) neler olduğunu anlatmak istedim.
Örneğin bir tabloya yeni bir kayıt INSERT etmek istediğinizde bu işlemin Transaction Log dosyasına nasıl kaydedildiğini anlatayım. Bunun için test veritabanımda aşağıdaki gibi bir tablo oluşturuyorum:
CREATE TABLE [dbo].[tablom1](
[alan1] [tinyint] NULL
) ON [PRIMARY]
GO
Daha sonra aşağıdaki komut ile bu tabloya bir kayıt giriyorum
INSERT INTO tablom1 VALUES(6)
Daha sonra sys.fn_dblog TVF'ı ile Transaction Log dosyasını sorguluyorum. sys.fn_dblog TVF'ı iki tane parametre alır. Birincisi StartLSN, diğeri de EndLSN. Yani Log Sequence Number (LSN) başlangıcı ve bitişini tanımlayıp sorgulayabiliyorsunuz. LSN, her bir işlem için verilmiş eşsiz bir değerdir, 3 bölümden oluşur, ilgi VLF (Vitual Log File) numarası, ikincisi VLF içerisindeki blok numarası (bir VLF içerisinde birden fazla Transaction bulunabilir), üçüncüsü de işlem sıra numarasıdır.
Not: Transaction Log dosyası kendi içinde de mimari olarak Virtual Log File'lardan oluşur, bunlar da aralarında Active ve Passive olarak ayrılır.
Bu iki parametreyi NULL olarak belirterek de çalıştırabilirsiniz, ki genelde de böyle kullanılır:
SELECT * FROM sys.fn_dblog(NULL, NULL)
![]() |
| Commit Transaction |
Eğer yukarıdaki INSERT komutunu çalıştırırsanız (ve sonrasında başka bir işlem yapmazsanız) sys.fn_dblog'u sorguladığınızda hemen yukarıdaki gibi bir sonuçla karşılaşacaksınız. Operation alanındaki değerleri tek tek açıklamak bu yazımın konusunun dışında, ama kırmızı dikdörtgen ile işaretlediğim alan içerisinde (Transaction ID'ye dikkat) işaretlediğim Implicit Transaction işlemini (INSERT işlemi için BEGIN TRAN ile Explicit Transaction oluşturmadık, fakat biz bunu yapmasak da her işlem bir Transaction'dır bu nedenle eğer biz tanımlamazsak bile işlemler Implicit Transaction ile çalıştırılır) açıklamaya çalışayım. LOP_BEGIN_ XACT ile Transaction'ımız başlatılmış olur, bununla LOP_COMMIT_XACT (veya işlem Rollback edildiyse de LOP_ABORT_XACT) arasında kalan işlemler gerçekleştirilmiş olur. Yukarıdaki örnekte LOP_BEGIN_XACT ile Transaction'ımızın başladığını, LOP_INSERT_ROWS ile INSERT işlemimizin gerçekleştiğini ve LOP_COMMIT_XACT ile de işlemimizin Commit edildiğini görebilirsiniz. Yani INSERT işlemimiz için Transaction Log dosyasında 3 adet kayıt oluşturulmuş oldu.
Peki Rollback'te ne oluyor? Hemen bunu da test edelim. Aşağıdaki komutu çalıştırıyorum ve bu şekilde Ornek adında bir Transaction'ı Explicitly oluşturmuş oluyorum. Ardından INSERT işlemimi gerçekleştiriyorum ve sonrasında da Transaction'ımı Rollback etmek için de ROLLBACK TRAN komutunu çalıştırıyorum. Sizce Transaction Log dosyasında kaç tane kayıt oluşmuş olacak?
BEGIN TRAN Ornek
INSERT INTO tablom1 VALUES(6)
INSERT INTO tablom1 VALUES(7)
INSERT INTO tablom1 VALUES(8)
ROLLBACK TRAN Oren
Sonuç aşağıdaki gibi:
SELECT * FROM sys.fn_dblog(NULL, NULL)
![]() |
| Rollback Transaction |
Belki UPDATE için durumun ne olacağını merak ediyor olabilirsiniz, örneğin 100 kayıtlık bir UPDATE işleminiz Rollback olduğunda ne mi oluyor? Tablomuzda 100 adet kayıt varken aşağıdaki komutu çalıştırdığımızda:
UPDATE tablom1 SET alan1 = 0
ve sys.fn_dblog ile sorguladığımızda Transaction için yapılan kayıt haricinde 100 adet LOP_MODIFY_ROW işlemi görüyoruz. Rollback işleminde de tüm bu kayıtlara yine 100 adet kayıt ekleniyor!
Bu nedenlerle, özellikle uzun süren DML işlemleriniz sonucu siz elle veya kendiliğinden (bir hata sonrası) Rollback işlemi gerçekleştiğinde Transaction Log dosyanızın bulunduğu diskte yeterli derecede boş alan olduğundan emin olmanızda fayda var. Örneğin çok büyük bir işlem gerçekleştirdiniz diyelim ve bu işlem herhangi bir nedenden dolayı Rollback oldu diyelim ve tüm bunların neticesinde de Transaction Log dosyanız doldu ve hatta bulunduğu diski de doldurdu diyelim, ne mi olur? Veritabanınız Suspect duruma düşer! Ve bunun olmasını kesinlikle istemezsiniz. Bu nedenle Rollback işlemlerini özellikle kontrollü bir şekilde yapacağınız zaman bu paylaştığım bilgileri aklınızda tutun, gerekli önlemleri alın, özellikle Transaction Log dosyanızın doluluk oranını, disk doluluk oranlarını iyi ve güvenli bir şekilde takip ettiğinizden emin olun.
Sevgiler,
Ekrem Önsoy
4 Kasım 2014 Salı
Transaction Log dosyası hakkında 2 ilginç ve komik gerçek
Merhabalar!
Sağolsun Paul Randal sayesinde SQL Server'ın derinlikleri hakkında ilginç bilgiler edinebiliyoruz.
Paul'ün verdiği bilgilere göre, Transaction Log dosyalarının mimari yapısında bulunan VLF (Virtual Log File)'lerdeki log blokları en fazla 60K'lık veri barındırabilirmiş. Bir gün merak etmiş ve Transaction Log'un mimarisinden sorumlu bölümdeki adamla konuşmuş bu konuyu. Demiş ki, örneğin neden 64K değil de 60K'dır bunun üst sınırı? Adam da "bunun nedenini kimse bilmiyor" demiş, bunun dokümantasyonu yokmuş, ilginç ve hatta komik değil mi? =)
Yine Paul'den öğrendiğime göre bir Transaction Log dosyasının içeriğini DBCC LOGINFO komutuyla incelediğimizde raporlanan değerlerden "Status" değeri "0" olursa, bu o VLF'in "inactive" olduğunu, değer "2" olursa VLF'in "active" olduğunu gösteriyor; fakat "1"in ne anlama geldiğini kimse bilmiyor, eskiden her ne için ayrıldıysa, artık hatırlanmıyor ve dokümante edilmemiş =)
SQL Server'ın karanlık ve derin dehlizlerinde gezinmeye devam!
Sevgiler,
Ekrem Önsoy
Sağolsun Paul Randal sayesinde SQL Server'ın derinlikleri hakkında ilginç bilgiler edinebiliyoruz.
Paul'ün verdiği bilgilere göre, Transaction Log dosyalarının mimari yapısında bulunan VLF (Virtual Log File)'lerdeki log blokları en fazla 60K'lık veri barındırabilirmiş. Bir gün merak etmiş ve Transaction Log'un mimarisinden sorumlu bölümdeki adamla konuşmuş bu konuyu. Demiş ki, örneğin neden 64K değil de 60K'dır bunun üst sınırı? Adam da "bunun nedenini kimse bilmiyor" demiş, bunun dokümantasyonu yokmuş, ilginç ve hatta komik değil mi? =)
Yine Paul'den öğrendiğime göre bir Transaction Log dosyasının içeriğini DBCC LOGINFO komutuyla incelediğimizde raporlanan değerlerden "Status" değeri "0" olursa, bu o VLF'in "inactive" olduğunu, değer "2" olursa VLF'in "active" olduğunu gösteriyor; fakat "1"in ne anlama geldiğini kimse bilmiyor, eskiden her ne için ayrıldıysa, artık hatırlanmıyor ve dokümante edilmemiş =)
SQL Server'ın karanlık ve derin dehlizlerinde gezinmeye devam!
Sevgiler,
Ekrem Önsoy
1 Kasım 2014 Cumartesi
Transaction Log dosyanızın boyutunun önemi
Merhaba,
Özellikle bir veritabanı yöneticisinin henüz ayak basmadığı ortamlarda, veritabanlarının Recovery Model'larının Full olduğunu defalarca gördüm. Tabii ki bunu tek başına bir "hata" olarak değerlendiremeyiz, fakat maalesef bahsini ettiğim bu tür ortamlarda veritabanlarının nasıl yönetildiği pek bilinmediği için Transaction Log dosyalarının boyutları veritabanının veri dosyalarının defalarca katı şeklinde büyük olabiliyor. Tabii ki sorun sadece Full Recovery Model'ın yönetilememesinden de kaynaklanmıyor, aynı zamanda tek seferde yapılan uzun süreli DELETE ve UPDATE işlemleri de Transaction Log dosyasının aşırı büyümesine neden olabiliyor.
Peki Transaction Log dosyasının aşırı büyümesinden neden bahsetmek istedim? Çünkü Transaction Log dosyasının boyutu, sizin özellikle bir sorun anında dönüşünüzü geciktirecektir. Bu da, özellikle sıkıntılı anlarda sıkıntının daha uzun süre devam etmesine neden olur. Zamanımızda Down Time'ın uzun sürmesi, malum müşteri ve para kaybı anlamına gelmektedir. Hatta bu sürecin doğru şekilde yönetilememesi bazılarının işine ve kariyerine de mal olabilmektedir.
Transaction Log dosyasının aşırı büyümesine sayılarla örnek vereyim. Örneğin Veritabanı veri dosyalarının 60GB boyutunda olduğu, Transaction Log dosyasının ise 180GB olduğu bir ortamı düşünün. Bazılarınız çok şaşırıyor ve bu değerleri abartılı buluyor ve kabul etmiyor olabilir; fakat bunlar bizim piyasada kendi gözlerimizle görebildiğimiz değerlerdir.
"Instant File Initialization" diye bir şeyi bazılarınız önceden duymuş, bazılarınız duymamış olabilir; kısaca bahsedeyim, bu özelliğin etkin olması örneğin bir yedekten dönme işlemi yaparken (Restore Database), yine örneğin 60GB'lık dosyanızın anında oluşturulmasını sağlayacaktır. Aksi takdirde, yani varsayılan ayarlarla 60GB'lık dosyanın oluşması için (tabii ki dosya içerisindeki boş alanlardan bahsediyorum) sıfırlama işleminin yapılması gerekiyor. Mesela 60GB'lık veri dosyanızın 25GB'ı ayrılmış ve boş alan (Rezerved) diyelim, o zaman siz veritabanınızı Restore ederken bu 25GB'lık alanda sıfırlama işlemi gerçekleşecek ve bu işlem bitinceye kadar da Restore işleminiz devam edecek. Instant File Initialization özelliğini kullandığınız zaman ise 25GB'lık alanın sıfırlama işlemini beklemeyeceksiniz. Bununla birlikte, Instant File Initialization özelliği sadece veri dosyaları için kullanılabiliyor. Transaction Log dosyamızın boyutu eğer 180GB ise, Instance File Initialization etkin bile olsa 180GB'lık alanın sıfırlanması işleminin bitmesini beklememiz gerekiyor. Bu da haliyle bir felaket senaryosunda hiç istemeyeceğimiz bir şey.
Bu nedenle özellikle herhangi bir nedenden dolayı veritabanı yöneticisiz çalışmak zorunda kalan arkadaşlarım, aman siz siz olun Recovery Model'ların ve Transaction Log dosyalarının nasıl yönetildiğini iyice öğrenin. Aksi takdirde zor durumlarla karşı karşıya kalabilirsiniz.
Kolay gelsin,
Ekrem Önsoy
Özellikle bir veritabanı yöneticisinin henüz ayak basmadığı ortamlarda, veritabanlarının Recovery Model'larının Full olduğunu defalarca gördüm. Tabii ki bunu tek başına bir "hata" olarak değerlendiremeyiz, fakat maalesef bahsini ettiğim bu tür ortamlarda veritabanlarının nasıl yönetildiği pek bilinmediği için Transaction Log dosyalarının boyutları veritabanının veri dosyalarının defalarca katı şeklinde büyük olabiliyor. Tabii ki sorun sadece Full Recovery Model'ın yönetilememesinden de kaynaklanmıyor, aynı zamanda tek seferde yapılan uzun süreli DELETE ve UPDATE işlemleri de Transaction Log dosyasının aşırı büyümesine neden olabiliyor.
Peki Transaction Log dosyasının aşırı büyümesinden neden bahsetmek istedim? Çünkü Transaction Log dosyasının boyutu, sizin özellikle bir sorun anında dönüşünüzü geciktirecektir. Bu da, özellikle sıkıntılı anlarda sıkıntının daha uzun süre devam etmesine neden olur. Zamanımızda Down Time'ın uzun sürmesi, malum müşteri ve para kaybı anlamına gelmektedir. Hatta bu sürecin doğru şekilde yönetilememesi bazılarının işine ve kariyerine de mal olabilmektedir.
Transaction Log dosyasının aşırı büyümesine sayılarla örnek vereyim. Örneğin Veritabanı veri dosyalarının 60GB boyutunda olduğu, Transaction Log dosyasının ise 180GB olduğu bir ortamı düşünün. Bazılarınız çok şaşırıyor ve bu değerleri abartılı buluyor ve kabul etmiyor olabilir; fakat bunlar bizim piyasada kendi gözlerimizle görebildiğimiz değerlerdir.
"Instant File Initialization" diye bir şeyi bazılarınız önceden duymuş, bazılarınız duymamış olabilir; kısaca bahsedeyim, bu özelliğin etkin olması örneğin bir yedekten dönme işlemi yaparken (Restore Database), yine örneğin 60GB'lık dosyanızın anında oluşturulmasını sağlayacaktır. Aksi takdirde, yani varsayılan ayarlarla 60GB'lık dosyanın oluşması için (tabii ki dosya içerisindeki boş alanlardan bahsediyorum) sıfırlama işleminin yapılması gerekiyor. Mesela 60GB'lık veri dosyanızın 25GB'ı ayrılmış ve boş alan (Rezerved) diyelim, o zaman siz veritabanınızı Restore ederken bu 25GB'lık alanda sıfırlama işlemi gerçekleşecek ve bu işlem bitinceye kadar da Restore işleminiz devam edecek. Instant File Initialization özelliğini kullandığınız zaman ise 25GB'lık alanın sıfırlama işlemini beklemeyeceksiniz. Bununla birlikte, Instant File Initialization özelliği sadece veri dosyaları için kullanılabiliyor. Transaction Log dosyamızın boyutu eğer 180GB ise, Instance File Initialization etkin bile olsa 180GB'lık alanın sıfırlanması işleminin bitmesini beklememiz gerekiyor. Bu da haliyle bir felaket senaryosunda hiç istemeyeceğimiz bir şey.
Bu nedenle özellikle herhangi bir nedenden dolayı veritabanı yöneticisiz çalışmak zorunda kalan arkadaşlarım, aman siz siz olun Recovery Model'ların ve Transaction Log dosyalarının nasıl yönetildiğini iyice öğrenin. Aksi takdirde zor durumlarla karşı karşıya kalabilirsiniz.
Kolay gelsin,
Ekrem Önsoy
30 Eylül 2014 Salı
Transaction Log'a alternatif mi geliyor?
Merhaba!
Az önce TechEd 2014'te Always On ile ilgili bir sunumu izlerken Senior Program Manager Lead Luis Vargas'ın şöyle bir soruyu:
- Eğer Primary ile Secondary'ler arasındaki bağlantı koparsa, Primary'de Transaction Log'un şişmesini nasıl engelleriz?
Şöyle cevaplandırdığını duydum:
- Bugün Transaction Log büyümeye devam edecek, çünkü herhangi bir veriyi kaybetmek istemeyiz. Bu nedenle Transaction Log dosyası ancak tüm Secondary'ler ilgili Log'ları aldığında temizlenecektir (Truncate olacak). Örneğin eğer birkaç saatlik bir kesinti olduysa ve Transaction Log doluluğu tehlikeli bir noktaya geldiyse, o zaman ilgili replikaları Availibility Group'tan çıkarabilirsiniz ve bağlantı geri sağlandığında replikaları tekrar eklersiniz. Gelecekte bu Transaction'ları Transaction Log'un dışında başka bir yerde konumlandırmayı düşünüyoruz.
Bu sizin ne kadar ilginizi çeker bilemiyorum, ama benim çok ilgimi çekti!
Kolay gelsin,
Ekrem Önsoy
Az önce TechEd 2014'te Always On ile ilgili bir sunumu izlerken Senior Program Manager Lead Luis Vargas'ın şöyle bir soruyu:
- Eğer Primary ile Secondary'ler arasındaki bağlantı koparsa, Primary'de Transaction Log'un şişmesini nasıl engelleriz?
Şöyle cevaplandırdığını duydum:
- Bugün Transaction Log büyümeye devam edecek, çünkü herhangi bir veriyi kaybetmek istemeyiz. Bu nedenle Transaction Log dosyası ancak tüm Secondary'ler ilgili Log'ları aldığında temizlenecektir (Truncate olacak). Örneğin eğer birkaç saatlik bir kesinti olduysa ve Transaction Log doluluğu tehlikeli bir noktaya geldiyse, o zaman ilgili replikaları Availibility Group'tan çıkarabilirsiniz ve bağlantı geri sağlandığında replikaları tekrar eklersiniz. Gelecekte bu Transaction'ları Transaction Log'un dışında başka bir yerde konumlandırmayı düşünüyoruz.
Bu sizin ne kadar ilginizi çeker bilemiyorum, ama benim çok ilgimi çekti!
Kolay gelsin,
Ekrem Önsoy
4 Nisan 2008 Cuma
"Kayıt Dosyaları (Transaction Logs) ve Boyut Sorunu"
Merhaba arkadaşlar,
Giriş
SQL Server' da bir veritabanı temel olarak iki dosyadan oluşur. Bunlardan birisi verileri tutulduğu veri dosyasıdır. Diğeri de veri dosyasına karşı yapılan işlemlerin kayıtlarının tutulduğu kayıt dosyası (Transaction Log). Kayıt dosyasının boyutu zaman zaman veritabanına karşı yapılan işlemlere göre çok şişebilir ve bu dosyanın boyutunu düşürmek isteyebilirsiniz. İşte bu yazımda size bu konuda bilgi vereceğim.
Veri Dosyaları (Data Files)
İlk paragrafta sizlere veritabanının iki temel dosyadan oluştuğunu ve bunlardan birisinin de veri dosyası olduğunu söylemiştim. Veri dosyalarının uzantıları varsayılan olarak "*.mdf" tir. Fakat böyle olmak gibi bir zorunluluğu da yoktur. Bu sadece bir standarttır, fakat standartlara bağlı kalmak veya kendi standartlarınızı oluşturmak da çok önemli bir işlemdir.
Kayıt Dosyaları (Transaction Files)
Diğer temel olan dosya ve esas değinmek istediğim ise kayıt dosyasıdır. Kayıt dosyalarının da varsayılan uzantısı "*.ldf" tir. Gene veri dosyaları gibi bunların da dosya uzantılarının "*.ldf" olması zorunlu değildir.
Kayıt dosyasına birçok tip işlem kaydedilmektedir, aşağıdakiler bu işlemler arasındadır:
- Tüm işlemlerin başlangıç ve bitişi,
- INSERT, UPDATE ve DELETE gibi tüm veri değişiklikleri. Yani DML (Data Manipulation Language) işlemleri ve ayrıca DDL (Data Definition Language) işlemleri,
- Tüm "extent" ve "sayfa (page)" ayırma ve kapatma işlemleri,
- Bir tablo veya indeks oluşturma ve silme işlemleri...
Meselâ şöyle sorular geliyor: "Bir tablom var ve çok büyük. Tablonun iskeleti gerekiyor, ama içindeki verileri tamamen boşaltmak istiyorum. Fakat silmeye başlayınca kayıt dosyamın şiştiğini görüyorum. Acaba grup grup mu silsem ve sonra kayıt dosyamı küçültsem sonra aynı işlemleri sırasıyla tekrarlasam olur mu? Daha kolay bir yöntem yok mu?!" Var tabii, meselâ TRUNCATE TABLE ile bir tabloyu sildiğinizde, DELETE komutundan farklı olarak yaptığınız işlem kayıt dosyasına kaydedilmez.
Bazı arkadaşlar ise gerek habergruplarında gerekse de forumlarda şöyle sorular soruyorlar: "Veritabanımda indeksleme işlemi yapıyordum ve bir süre sonra 'kayıt dosyası doldu!' gibi bir hata alıyorum" diyorlar veya "İndeksleme işlemi yaparken kayıt dosyamın boyutunun çok arttığını fark ettim, bu dosyamın boyutu neden büyüyor? Kayıt dosyamı nasıl eski haline getirebilirim?" gibi gibi... Yukarıda da sıraladığım gibi, İndeksleme işlemi de kayıt dosyasında takip edilen bir işlemdir. Bu nedenle indeksleme işlemine dair tüm bilgiler kayıt dosyasına da saklanır. Yapacağınız indeksleme ne kadar geniş çaplıysa, kayıt dosyanız da ona eşit orantılı olarak büyüyecektir. Bu nedenle "kayıt dosyası doldu" hatası almamak için hem kayıt dosyanızın "dosya boyutu sınırı" ayarının düzgün yapılandırdığından, hem de kayıt dosyanızın bulunduğu diskte yeterli alan olduğundan emin olun.
Kayıt Dosyalarının Boyutlarını Küçültme
Kayıt dosyalarınızın boyutlarını küçültmek için ilk önce yedeklerini almanız gerekiyor veya doğrudan içlerindeki Pasif Sanal Kayıtları aşağıdaki örneklerde verdiğim gibi temizleyebilirsiniz:
BACKUP LOG veritabani_adi WITH TRUNCATE_ONLY
veya
BACKUP LOG veritabani_adi WITH NO_LOG
Bu komutlardan birini kullandıktan ve dolayısıyla kayıt dosyasının içerisindeki pasif sanal kayıtları temizledikten sonra, dosyanın fiziksel boyutunu küçültmek için DBCC SHRINKFILE komutunu kullanmalısınız. Aşağıdaki örnekte, Deneme_Log isimli kayıt dosyasının boyutu 1MB' a düşürülecektir. Bu komutu ise aşağıdaki örneğe göre kullanabilirsiniz:
DBCC SHRINKFILE (Deneme_Log, 1);
Not:
Burada göz önünde bulundurmanız gereken şey, kayıt dosyasının içerisindeki sanal kayıtların, en son aktif sanal kayda kadar silinebileceğidir. En son aktif sanal kayıttan daha sonrası silinemez, ta ki o aktif kayıt pasifleşinceye kadar. Aktif ve Pasif Sanal Kayıtlardan aşağıda söz edeceğim.
Ayrıca, bu konu hakkında SQL Server 2008' de bazı değişiklikler var. Bununla ilgili olan ve aşağıda adresini verdiğim makalemi de okuyabilirsiniz:
SQL Server 2008' de 'TRUNCATE_ONLY' ve 'NO_LOG' BACKUP Seçenekleri
Bununla birlikte, "Recovery Models" konusu da doğrudan kayıt dosyasının büyümesiyle alâkalı bir konudur. Meselâ bir kayıt dosyasının içini SIMPLE RECOVERY modelini kullanarak da belli aralıklarla temizleyebilirsiniz. Bu konuda da daha fazla bilgi almak için aşağıdaki makalemi okuyabilirsiniz:
Recovery Models: FULL, BULK LOGGED, SIMPLE
Kayıt dosyalarının dosya boyutlarını sürekli düşük bir değerde tutmak da marifet değildir. Aslında Veritabanı Yöneticisi olmayıp, ama kaynak olmadığı için de bu konuda bir uzmanla çalışamayan kişilerin sürekli bu tür hatalar yaptıklarını gözlemliyorum.
Aşağıdaki paragrafa geçmeden önce hemen kısaca Aktif Sanal Kayıt ve Pasif Sanal Kayıtlardan da bahsetmek istiyorum. Kayıt dosyası içerisindeki kayıtlar Aktif ve Pasif Sanal Kayıtlar olarak sınıflandırılır. Aktif Sanal Kayıtlar, "Rollback" işlemi için açılmış ve başarıyla devam eden işlemler silsilesindeki kayıtlardır. Bu kayıtlar ne kayıt dosyasının yedeği alınarak, ne de başka bir şekilde kesinlikle temizlenemezler. Pasif Kayıt Dosyaları ise, kayıt dosyasının yedeği alınarak temizlenebilir.
Peki neden kayıt dosyalarının boyutları çok düşük olmamalı ve ortamınıza özel belli bir değerde olmalı? Çünkü yukarıda da anlattığım gibi veritabanınızda işlemler gerçekleştirildikçe, bu işlemler kayıt dosyasına işlenirler. Metin dizeleri gibidir kayıt dosyaları da yani belli bir sıraya göre düzenlenir ve yeni işlemler hep sona eklenirler. Her işlemin bir LSN (Kayıt Sırası Numarası) i vardır. Siz işlem yaptıkça dosya büyür de büyür. Ve her büyüme esnasında Veritabanı Motoru işlemleri durdurup, kayıt dosyasının boyutunu büyütür ve işlemlere devam eder.
Şöyle bir örnek vereyim: Veri dosyası boyutu 80GB olan ve her gün veri girişi yapılan ve yoğun kullanılan bir veritabanınız olsun. Bunun kayıt dosyasının boyutunu ise her gün kayıt dosyası yedeğinin alınması işleminin ardından "DBCC SHRINKFILE\SHRINKDATABASE" gibi komutlar kullanarak veya "Maintanence Task" lar kullanarak küçülttüğünüzü varsayalım. Dosya büyüme oranı da 10MB olsun. Bunun anlamı şu dur, kayıt dosyasının yedeğini alma işlemiyle kayıt dosyanızın içindeki Pasif Sanal Kayıtları temizlersiniz, DBCC SHRINK işlemi ile de dosyanın fiziksel boyutunu küçültürsünüz; yani yeni işlemler için kayıt dosyasının içerisinde boşluk kalmaz. Bu nedenle, yeni işlemler için kayıt dosyasının fiziksel boyutunun büyütülmesi gerekir. Zaten yoğun kullanılan bir veritabanı ve büyüme değeri de sadece 10MB. Veritabanı Motorunun sürekli bu dosyanın boyutunu büyütmesi gerekeceği zaman nasıl bir sorunun oluşabileceğini görüyorsunuz değil mi? İşte bu, performans sorunlarına katkıda bulunabilecek önemli bir etkendir.
Sonuç
Gerekli gereksiz kayıt dosyasının küçültülmesi işleminin yapılmamasını tavsiye ederim. Kayıt dosyanızı belli bir büyüklük değerinde bırakın, sürekli büyüyüp küçülmesi gerekmesin. SHRINK işlemlerini gerektiğinde siz yapın, otomatikleştirmeyin. Ayrıca otomatik dosya büyüme değeri için de küçük değerler kullanmayın. Eğer yeriniz varsa bırakın rahatça büyüsün. Ama 80GB' lık veritabanında da 50GB kayıt dosyası olsun demiyorum tabi, yazımın belli yerlerinde de dediğim gibi, her ortamın kendine has özellikleri ve ihtiyaçları vardır. Siz de ayarlarınızı kendi durumunuza uygun yapın.
Ekrem Önsoy
Giriş
SQL Server' da bir veritabanı temel olarak iki dosyadan oluşur. Bunlardan birisi verileri tutulduğu veri dosyasıdır. Diğeri de veri dosyasına karşı yapılan işlemlerin kayıtlarının tutulduğu kayıt dosyası (Transaction Log). Kayıt dosyasının boyutu zaman zaman veritabanına karşı yapılan işlemlere göre çok şişebilir ve bu dosyanın boyutunu düşürmek isteyebilirsiniz. İşte bu yazımda size bu konuda bilgi vereceğim.
Veri Dosyaları (Data Files)
İlk paragrafta sizlere veritabanının iki temel dosyadan oluştuğunu ve bunlardan birisinin de veri dosyası olduğunu söylemiştim. Veri dosyalarının uzantıları varsayılan olarak "*.mdf" tir. Fakat böyle olmak gibi bir zorunluluğu da yoktur. Bu sadece bir standarttır, fakat standartlara bağlı kalmak veya kendi standartlarınızı oluşturmak da çok önemli bir işlemdir.
Kayıt Dosyaları (Transaction Files)
Diğer temel olan dosya ve esas değinmek istediğim ise kayıt dosyasıdır. Kayıt dosyalarının da varsayılan uzantısı "*.ldf" tir. Gene veri dosyaları gibi bunların da dosya uzantılarının "*.ldf" olması zorunlu değildir.
Kayıt dosyasına birçok tip işlem kaydedilmektedir, aşağıdakiler bu işlemler arasındadır:
- Tüm işlemlerin başlangıç ve bitişi,
- INSERT, UPDATE ve DELETE gibi tüm veri değişiklikleri. Yani DML (Data Manipulation Language) işlemleri ve ayrıca DDL (Data Definition Language) işlemleri,
- Tüm "extent" ve "sayfa (page)" ayırma ve kapatma işlemleri,
- Bir tablo veya indeks oluşturma ve silme işlemleri...
Meselâ şöyle sorular geliyor: "Bir tablom var ve çok büyük. Tablonun iskeleti gerekiyor, ama içindeki verileri tamamen boşaltmak istiyorum. Fakat silmeye başlayınca kayıt dosyamın şiştiğini görüyorum. Acaba grup grup mu silsem ve sonra kayıt dosyamı küçültsem sonra aynı işlemleri sırasıyla tekrarlasam olur mu? Daha kolay bir yöntem yok mu?!" Var tabii, meselâ TRUNCATE TABLE ile bir tabloyu sildiğinizde, DELETE komutundan farklı olarak yaptığınız işlem kayıt dosyasına kaydedilmez.
Bazı arkadaşlar ise gerek habergruplarında gerekse de forumlarda şöyle sorular soruyorlar: "Veritabanımda indeksleme işlemi yapıyordum ve bir süre sonra 'kayıt dosyası doldu!' gibi bir hata alıyorum" diyorlar veya "İndeksleme işlemi yaparken kayıt dosyamın boyutunun çok arttığını fark ettim, bu dosyamın boyutu neden büyüyor? Kayıt dosyamı nasıl eski haline getirebilirim?" gibi gibi... Yukarıda da sıraladığım gibi, İndeksleme işlemi de kayıt dosyasında takip edilen bir işlemdir. Bu nedenle indeksleme işlemine dair tüm bilgiler kayıt dosyasına da saklanır. Yapacağınız indeksleme ne kadar geniş çaplıysa, kayıt dosyanız da ona eşit orantılı olarak büyüyecektir. Bu nedenle "kayıt dosyası doldu" hatası almamak için hem kayıt dosyanızın "dosya boyutu sınırı" ayarının düzgün yapılandırdığından, hem de kayıt dosyanızın bulunduğu diskte yeterli alan olduğundan emin olun.
Kayıt Dosyalarının Boyutlarını Küçültme
Kayıt dosyalarınızın boyutlarını küçültmek için ilk önce yedeklerini almanız gerekiyor veya doğrudan içlerindeki Pasif Sanal Kayıtları aşağıdaki örneklerde verdiğim gibi temizleyebilirsiniz:
BACKUP LOG veritabani_adi WITH TRUNCATE_ONLY
veya
BACKUP LOG veritabani_adi WITH NO_LOG
Bu komutlardan birini kullandıktan ve dolayısıyla kayıt dosyasının içerisindeki pasif sanal kayıtları temizledikten sonra, dosyanın fiziksel boyutunu küçültmek için DBCC SHRINKFILE komutunu kullanmalısınız. Aşağıdaki örnekte, Deneme_Log isimli kayıt dosyasının boyutu 1MB' a düşürülecektir. Bu komutu ise aşağıdaki örneğe göre kullanabilirsiniz:
DBCC SHRINKFILE (Deneme_Log, 1);
Not:
Burada göz önünde bulundurmanız gereken şey, kayıt dosyasının içerisindeki sanal kayıtların, en son aktif sanal kayda kadar silinebileceğidir. En son aktif sanal kayıttan daha sonrası silinemez, ta ki o aktif kayıt pasifleşinceye kadar. Aktif ve Pasif Sanal Kayıtlardan aşağıda söz edeceğim.
Ayrıca, bu konu hakkında SQL Server 2008' de bazı değişiklikler var. Bununla ilgili olan ve aşağıda adresini verdiğim makalemi de okuyabilirsiniz:
SQL Server 2008' de 'TRUNCATE_ONLY' ve 'NO_LOG' BACKUP Seçenekleri
Bununla birlikte, "Recovery Models" konusu da doğrudan kayıt dosyasının büyümesiyle alâkalı bir konudur. Meselâ bir kayıt dosyasının içini SIMPLE RECOVERY modelini kullanarak da belli aralıklarla temizleyebilirsiniz. Bu konuda da daha fazla bilgi almak için aşağıdaki makalemi okuyabilirsiniz:
Recovery Models: FULL, BULK LOGGED, SIMPLE
Kayıt dosyalarının dosya boyutlarını sürekli düşük bir değerde tutmak da marifet değildir. Aslında Veritabanı Yöneticisi olmayıp, ama kaynak olmadığı için de bu konuda bir uzmanla çalışamayan kişilerin sürekli bu tür hatalar yaptıklarını gözlemliyorum.
Aşağıdaki paragrafa geçmeden önce hemen kısaca Aktif Sanal Kayıt ve Pasif Sanal Kayıtlardan da bahsetmek istiyorum. Kayıt dosyası içerisindeki kayıtlar Aktif ve Pasif Sanal Kayıtlar olarak sınıflandırılır. Aktif Sanal Kayıtlar, "Rollback" işlemi için açılmış ve başarıyla devam eden işlemler silsilesindeki kayıtlardır. Bu kayıtlar ne kayıt dosyasının yedeği alınarak, ne de başka bir şekilde kesinlikle temizlenemezler. Pasif Kayıt Dosyaları ise, kayıt dosyasının yedeği alınarak temizlenebilir.
Peki neden kayıt dosyalarının boyutları çok düşük olmamalı ve ortamınıza özel belli bir değerde olmalı? Çünkü yukarıda da anlattığım gibi veritabanınızda işlemler gerçekleştirildikçe, bu işlemler kayıt dosyasına işlenirler. Metin dizeleri gibidir kayıt dosyaları da yani belli bir sıraya göre düzenlenir ve yeni işlemler hep sona eklenirler. Her işlemin bir LSN (Kayıt Sırası Numarası) i vardır. Siz işlem yaptıkça dosya büyür de büyür. Ve her büyüme esnasında Veritabanı Motoru işlemleri durdurup, kayıt dosyasının boyutunu büyütür ve işlemlere devam eder.
Şöyle bir örnek vereyim: Veri dosyası boyutu 80GB olan ve her gün veri girişi yapılan ve yoğun kullanılan bir veritabanınız olsun. Bunun kayıt dosyasının boyutunu ise her gün kayıt dosyası yedeğinin alınması işleminin ardından "DBCC SHRINKFILE\SHRINKDATABASE" gibi komutlar kullanarak veya "Maintanence Task" lar kullanarak küçülttüğünüzü varsayalım. Dosya büyüme oranı da 10MB olsun. Bunun anlamı şu dur, kayıt dosyasının yedeğini alma işlemiyle kayıt dosyanızın içindeki Pasif Sanal Kayıtları temizlersiniz, DBCC SHRINK işlemi ile de dosyanın fiziksel boyutunu küçültürsünüz; yani yeni işlemler için kayıt dosyasının içerisinde boşluk kalmaz. Bu nedenle, yeni işlemler için kayıt dosyasının fiziksel boyutunun büyütülmesi gerekir. Zaten yoğun kullanılan bir veritabanı ve büyüme değeri de sadece 10MB. Veritabanı Motorunun sürekli bu dosyanın boyutunu büyütmesi gerekeceği zaman nasıl bir sorunun oluşabileceğini görüyorsunuz değil mi? İşte bu, performans sorunlarına katkıda bulunabilecek önemli bir etkendir.
Sonuç
Gerekli gereksiz kayıt dosyasının küçültülmesi işleminin yapılmamasını tavsiye ederim. Kayıt dosyanızı belli bir büyüklük değerinde bırakın, sürekli büyüyüp küçülmesi gerekmesin. SHRINK işlemlerini gerektiğinde siz yapın, otomatikleştirmeyin. Ayrıca otomatik dosya büyüme değeri için de küçük değerler kullanmayın. Eğer yeriniz varsa bırakın rahatça büyüsün. Ama 80GB' lık veritabanında da 50GB kayıt dosyası olsun demiyorum tabi, yazımın belli yerlerinde de dediğim gibi, her ortamın kendine has özellikleri ve ihtiyaçları vardır. Siz de ayarlarınızı kendi durumunuza uygun yapın.
Ekrem Önsoy
Kaydol:
Kayıtlar (Atom)

