14 Kasım 2014 Cuma

Transaction Log Shipping Status report

Hello there,

I realise that a good amount of DBAs do not take advantage of the built-in reports in the SQL Server Management Studio (SSMS). I have been using Log Shipping in the production servers for more than 7 years. I have used in-house developer tools to monitor the status of my log shipped databases and SSMS' built-in reports. Every shop can not build their own monitoring tools and some do not have a budget to buy a 3rd party tool; but everyone can benefit from the built-in reports of SSMS!

When it comes to IT generally, monitoring is crucial; with this in mind, to a DBA, monitoring is everything. We manage our systems with monitoring tools. Some need to act proactively and others to react to problems before our managers or users start yelling at us.

Oh , yea, I would write something about monitoring Log Shippings. If yours is a small shop and if you are a small shop probably you will have a primary production server and probably you will configure Log Shipping only on that primary server, then you can use SSMS' Transaction Log Shipping Status report. I wanted to stress out this report because I do not see people write about it on the internet. So I thought this report could be beneficial to junior DBAs or some shops who does not have a DBA or some IT professionals (I call them "all-in-one", no offence!) who has to carry about every IT related stuff in the office.

Here's a screen shot about the report I am talking about:

Transaction Log Shipping Status report

I had to crop the left side of the report because it was too large to fit on my screen, besides I would blur it all that column as they are the database names of one of my production servers.

Anyway, as you can see from the screenshot above, you can see everything you need to know about the status of a database's Log Shipping. How long it's been the last backup has been performed, the threshold and if the alert would be triggered if the threshold was crossed and the details about other fundamental jobs, Copy and Restore of Log Shipping.

Here's how you can open this report:
- Open SSMS and go to Object Explorer,
- Right click on the SQL Server Instance name and select "Reports" and then "Standard Reports"
- You will see "Transaction Log Shipping Status" report at the bottom of the list, click on it and there you go.

You will see much more reports about server monitoring in this chest, you can play with them to learn more.

I hope it helps!

Cheers,
Ekrem Önsoy

12 Kasım 2014 Çarşamba

Idera: Another awful experience with Compliance Manager

Hi folks!

For more than a year I have been using Idera's Compliance Manager (CM) tool which is as its name refers, a compliance tool. I actually have created lots of tickets because of lots of problems with this tool during this period of time. I guess some of you may find this comment enough to keep away from this tool, especially for a production environment, but for the others let me tell you a fresh story I have just experienced this morning.

Last night I enabled Before/After feature for a specific table's some specific fields to collect detailed information about the modifications and as I thought its agent sends the records from the source to the target I observed for any change in the repository database, but I saw nothing spectacular in the row size of the tables. However this morning, clients began screaming with the following kind of errors:

ErrorQuery: SELECT 'Error.  Table: dbo.xxx, Error: Invalid object name ''SQLcompliance_Data_Change.SQLcompliance_Changed_Data_Table''.' Message FROM [SQLcompliance_Data_Change].[SQLcompliance_Changed_Data_Table] WHERE 1 = 0An error occurred sending error message query: Invalid object name 'SQLcompliance_Data_Change.SQLcompliance_Changed_Data_Table'.Invalid object name 'SQLcompliance_Data_Change.SQLcompliance_Changed_Data_Table'.The statement has been terminated.

The name of the table, which I replaced with "xxx" in the error message, was the one I enabled for Before/After data collection. As soon as I saw this error message, I thought CM might had created some DML Triggers on this critical table and this was the case indeed! I immediately shutdown CM's agent service, dropped the trigger and cleared this configuration from the properties of the related database from the CM's console.

Then according to the feedbacks from the end users the problem was solved, then I dug into the problem to understand more about the "SQLcompliance_Data_Change" schema, as it's in front of the table name, I assumed it's a schema. However, neither the schema nor the table were there! The database that I had this problem did not contain them. So it turned out that CM would keep these records in the production database itself, like a CDC configuration. But it skipped or failed to create the schema and table, it only created the trigger and our most critical production database went down!

For those who consider using this tool in their production environment, god bless you my friends...

Cheers,
Ekrem Önsoy

Heads up! A "gotcha" about FCI.


Hello there,

I was watching the presentation of Ryan Adams in the SQL PASS Summit 14 from PASSTV and he was talking about a "gothca" of SQL Server Failover Clustering Instances, I wanted to spread it a little bit further, so that's why I'm sharing about it.

The thing is, you can now locate your TEMPDB on a local drive (like an SSD disk) when you set up a SQL Server Failover Clustered Instance. The directory will be created by the SQL Server Setup and the permissions to that directory will be granted by the Setup again, but this will be done only for the first node of the cluster! When you add the second node to the cluster, that same directory with the same path will not be created on that node and of course because of this a permission will not be granted. He mentions that you will be warned about this only once during the setup of the first node and you will not be warned when you were adding the other node. So you have to be careful about it as the SQL Server resources can not be brought online as the TEMPDB can not be created if the directory with the same path does not exist at the other node.

Cheers,
Ekrem Önsoy

11 Kasım 2014 Salı

Sneak peak: Strecthing tables into Azure!

Merhaba arkadaşlar,

Maalesef bu sene de PASS Zirvesine katılamadım, fakat arayı kapatmak için PASSTV'den faydalanmaya çalışıyorum. PASS'ın başındaki adam olan Thomas LaRock'ın Keynote'unu izlerken ilginç bir şey dikkatimi çekti; Rengarajan, bir mühendis yardımıyla bir veritabanındaki tablodaki sıcak verinin (güvenlik veya performans amacıyla) yerel sunucunuzda barındırılıp soğuk verinin (örneğin arşivlenecek veya seyrek olarak sorgulanacak veya hassas olmayan) Azure'a uzatılabileceğinden bahsetti. Konu başlığında da belirttiğim gibi bu yeni ve adı resmen konmuş bir özellik değil; yani ne Azure'un ne de SQL Server'ın bir sonraki versiyonuna gelecek diye bir şey denmedi. Sadece ucundan tanıtımı yapılmış oldu, ama bence gelecek vaadeden ve yakın gelecekte yeni versiyonlara eklenecek bir özellik gibi görünüyor.

Sunumdan bir ekran görüntüsünü aşağıda paylaşıyorum:


Bahsini ettiğim Keynote'u da buradan izleyebilirsiniz:

Bu özelliğin altyapısının nasıl olduğundan falan da bahsedilmedi, fakat sunumda birkaç komut görülebiliyor. Örneğin replikasyon şu şekilde dondurulabiliyor:

ALTER TABLE PAUSE STRETCH;

Veya aşağıdaki komut ile tekrar devam ettirilebiliyor:

ALTER TABLE RESUME STRETCH;

Şunu da eklemek isterim, replikasyon devam ederken tabloda işlem yapmaya devam edebiliyorsunuz.

Kolay gelsin,
Ekrem Önsoy

6 Kasım 2014 Perşembe

İpucu: Full Recovery Model

Merhaba,

Örneğin aşağıdaki komut ile önceden Recovery Model'ı SIMPLE olan bir veritabanınızın Recovery Model'ını FULL yaptığımızı varsayalım:

ALTER DATABASE AdventureWorks2012 SET RECOVERY FULL

Bazıları, sadece bu komutu çalıştırdıktan sonra AdventureWorks2012 veritabanının Recovery Model'ının FULL olarak ayarlandığını düşünebilir, aslında öyle olmuş gibi de görünüyor; fakat her ne kadar metadata'sı böyle görünse de pratikte AdventureWorks2012 veritabanı Full Recovery Model davranışlarını göstermez, ta ki BACKUP DATABASE komutuyla veritabanınızın tam olarak yedeğini alıncaya kadar…

Kolay gelsin,
Ekrem Önsoy

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)

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
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


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

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