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

24 Ekim 2014 Cuma

Olmayan Core ile sahte paralelizm

Merhaba!

Bugün yine Itzik'in bir yazısını okurken yeni bir şey öğrendim, sizlerle de paylaşmak istedim.

Örneğin SQL Server veritabanı uygulamalarınız için bir test ortamı oluşturdunuz; fakat test sunucunuzun donanımı üretim sunucunuz kadar güçlü değil, ki genelde de böyledir. Haklı olarak test ortamında çalıştırdığınız sorgular için üretilen Execution Plan'lar ile üretim ortamındakiler aynı olsun istiyorsunuz. 

Bunun için test ortamındaki SQL Server Instance'ını -P parametresiyle başlatabiliyoruz, bunu zaten SQL Server ile haşır neşir olan çoğumuz bilir. Bilmeyenler için de şöyle izah edeyim, SQL Server Configuration Manager'ı açın, ilgili SQL Server Database Engine servisinizin özelliklerine gidin ve Startup Parameters'a -Pn parametresini ekleyin, n burada CPU Core sayısı olarak duruyor. Yani örneğin -P8 eklemiş olursanız, fiziksel makineniz 4 Core'lu da olsa SQL Server 8 Core varmış gibi üretecek Execution Plan'ları. Tabii ki bu değişikliğin etkinleşebilmesi için SQL Server Database Engine servisinizi yeniden başlatmanız gerekecek.

Bilmediğim ve çoğu kişinin de bilmediği yöntem ise aşağıdaki yöntem. Bu yöntem Undocumented bir yöntem, yani Microsoft tarafından dokümantasyona eklenmemiş, yani resmen desteklenmiyor. Bir şekilde, ya bir Microsoft çalışanı tarafından resmi olmayan bir şekilde bir yerde yazıldı çizildi de biliniyor ya da bir yerdeki CSS'ten biri veya bir PFE bir müşteride kullandı da öğrenildi.

Peki nedir bu yöntem? Nasıl kullanılır? İnternette bu yöntem hakkında çok bilgi yok şu anda. Komut ise aşağıdaki gibi:

DBCC OPTIMIZER_WHATIF(1,8);

Eğer bu komutu çalıştırırsanız, hiç yukarıdaki -P parametresinde olduğu gibi SQL Server servisini yeniden başlatmanız falan gerekmeyecek. Bu komutnu etkisi, sadece içinde bulunduğunuz oturum için geçerli olacak.

Oturumunuzu yine normal seyrine çevirmek isterseniz de bu komutu aşağıdaki parametrelerle çalıştırabilirsiniz:

DBCC OPTIMIZER_WHATIF(1,0);

Ekrem Önsoy

23 Ekim 2014 Perşembe

Sequence ve Identity kullanımında atlamalara dikkat!

Merhaba,

Bu sabah aşağıdaki makaleyi okurken Identity'lerdeki atlamaların mantığını anladım. Kendi makinemdeki test amaçlı kurulu bir VM'de de test ettim.

Öncelikle bu sorunu bir projede fark etmiştim, bir kişinin makinesine (dizüstü bilgisayar) bir veritabanıyla birlikte çalışan bir uygulama kurmuştuk, SQL Server Express Edition'ı da yükledik tabii makineye. Sonra zaman zaman tablolardaki Identity değerlerinde zıplamalar olduğunu görmüş, ama buna anlam verememiştik.

Aşağıdaki Itzik'in makalesinde nedeni anlaşılıyor. Yaptığım testlerde de doğruladım. Örneğin aşağıdaki gibi bir tablo oluşturun:

-- Tablo oluştur
CREATE TABLE t1_identityCacheTest(i INT IDENTITY(1,1))
-- İçine kayıt koy
INSERT INTO t1_identityCacheTest DEFAULT VALUES
INSERT INTO t1_identityCacheTest DEFAULT VALUES
-- Kayıtları göster
SELECT * FROM t1_identityCacheTest
-- Sonuç:
2
-- SQL Server Instance'ı bir Failover Clustering senaryosunda Failover oluyormuş gibi veya bir Availability Groups senaryosunda Node değiştiriyormuş gibi birden servis kapansın (Task Manager -> End process).

-- SQL Server servisini tekrar başlat
-- İçine kayıt koy
INSERT INTO t1_identityCacheTest DEFAULT VALUES
-- Kayıtları göster
SELECT * FROM t1_identityCacheTest
-- Sonuç:
1002

Bunun nedeni ise SQL Server 2012 ile birlikte artık varsayılan olarak Identity (ve tabii Sequence için) Cache kullanılması. Cache kullanılması Identity ve Sequence performansı için çok iyi oluyor, performans testini de yapmış Itzik.

Arkadaşın makineye kurduğumuz uygulamanın Identity'li tablolarındaki atlamanın nedeni ise, adamın dizüstü makinesini çat diye kapıyor oluşuydu.

Bunların yanında şunu da tekrar hatırlatmakta fayda var, Cache kullanılmasa bile Identity'lerde atlama / boşluk olasılığı her zaman var, örneğin hata alan bir işleminizdeki Identity numarasının boş kalması gibi...

Itzik'in makalesi:

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

19 Eylül 2014 Cuma

Database Corruption

Arkadaşlar merhaba,

Az önce bir arkadaşım telaşlı bir durumda aradı ve kısa bir süre sonra telaşının nedeni anlaşıldı. 150GB boyutundaki bir veritabanı Corrupt olmuştu.

Bu arkadaşım çalıştığı firmada sistem yöneticisi olarak çalışıyor ve birçok konuda kendisi sorumlu. Windows ve diğer işletim sistemlerinin yönetiminden, ağdan, güvenlikten ve veritabanından gibi. Daha geçenlerde görüşmüştük kendisiyle ve bana şirketinin bütçe ayırmadığından dolayı veritabanı yönetimi konusunda danışmanlık hizmeti alamadığından yakınmıştı.

"Umarım dokunmadın?" dedim, "Dokundum…" dedi. "Ne yaptın?" dedim, "internetten okudum ve DBCC CHECKDB…" derken lafını kestim, "ALLOW_DATA_LOSS parametresiyle çalıştırdın değil mi?" dedim "Evet, 15 saattir devam ediyor. Ne yapabiliriz?" dedi. Bu noktada kendisine yapabileceğim hiçbir şey kalmadığını, bu veritabanına dair en iyi yedeği bulması gerektiğini, eğer sorun güç kesintisindense bunu, SAN'dense onu düzeltip yedekten öyle dönmesi gerektiğini söyledim.

DBCC CHECKDB komutunu Microsoft'ta baştan sona tekrar yazan kişi Paul S. Randal'dır, kendisiyle daha dün başka bir konuda gece e-posta yoluyla konuşuyorduk. Paul DBCC CHECKDB ile ilgili verdiği derslerde, yazdığı makalelerde özellikle ve bıkmadan vurgular, veritabanınız Corrupt olduysa, DBCC CHECKDB'yi "ALLOW_DATA_LOSS" komutuyla çalıştırmak eğer yedeğiniz de yoksa ve o kadar çaresizseniz ve bol bol da vaktiniz varsa ancak o zaman yapılabilirdir.

Bununla birlikte, lütfen ama lütfen beni veya başka bir SQL Server danışmanını Corruption hakkında internetten okuyup bir şeyler uyguladıktan sonra değil, önce arayın. Çünkü yaptığınız her müdahale ile bizim bir şeyleri kurtarma ihtimalimizi azaltıyorsunuz.

Bir veritabanınız herhangi bir nedenden dolayı kullanılamaz duruma geldiğinde ilk bakacağınız şey yedekleriniz olmalı. Ardından eğer veritabanınızı o durumdan kurtarma ihtimalinizi değerlendirmek istiyorsanız ve kurumunuzun bünyesinde de deneyimli bir veritabanı uzmanı yoksa lütfen bir veritabanı danışmanına başvurun.

Lütfen sağlıklı işleyen bir yedekleme stratejiniz olduğundan emin olun, emin olamıyorsanız yine bir veritabanı danışmanına başvurun. Ayrıca sadece veritabanlarınızın yedeklerini almakla yetinmeyin, güzel ve işleyen bir veritabanı yedek kontrol sisteminiz olduğundan da emin olun. Unutmayın, şirketlerin en değerli varlıkları verilerdir.

Ekrem Önsoy

9 Eylül 2014 Salı

CHOOSE fonksiyonu

Merhaba arkadaşlar,

SQL Server'daki CHOOSE fonksiyonunu biliyor muydunuz? Bu fonksiyon SQL Server 2012 ile birlikte geldi. 

SELECT ..., 'xxx' = CASE WHEN yyy = 1 THEN 'xy' ... END ...

Yukarıdaki örnekteki gibi durumlar için pratik bir kullanım sağlayabilir CHOOSE komutu. Örneğin:

SELECT CHOOSE (alan1, 'Manager', 'Director', 'Developer', 'Tester' ) AS Result FROM tablom1;

CHOOSE ile yukarıdaki yazdığım komutun CASE WHEN'lisi şöyle:

SELECT 'Result' = CASE WHEN alan1 = 1 THEN 'Manager'  WHEN alan1 = 2 THEN 'Director' WHEN alan1 = 3 THEN 'Developer' WHEN alan1 = 4 THEN 'Tester' END FROM tablom1

Performans açısından bir katkısı yok, ama dediğim gibi kod yazma konusunda kolaylık sağlıyor.

Bu fonksiyon hakkında daha fazla bilgi için BOL'dan faydalanabilirsiniz:

Ekrem Önsoy

27 Ağustos 2014 Çarşamba

TransSQL: SQL Server ortamlarınıza kod taşıma

Merhaba arkadaşlar,

Bir süredir bu bloguma bir şey yazamadım, takip eden arkadaşlarımın tahmin ettiği gibi TransSQL isimli SQL Server ortamları arasında kod taşıma işini yapan uygulamamızın geliştirilmesi konusunda harıl harıl çalışmalarımıza devam ediyoruz.

Sağolsun Yiğit Aktan, Yavuz Selim Akbulut, İlker Usta ve Turgay Sahtiyan gibi deneyimli Veritabanı Yöneticisi arkadaşlarımın, Semerkand Grup'ta IT Direktörü olan Murat Demirkıran'ın ve İş Analisti olan eşim Selin Bilge Kurt Önsoy'un da değerli yorumları ve destekleriyle iyi bir noktaya geldik.

Henüz bir "demo" versiyon yok, demo versiyonu sizlerle bu senenin sonuna doğru paylaşmayı umut ediyorum. O vakte kadar tamamlamamız gereken bazı dokümantasyon, işlevsellik testi ve güvenlik ile ilgili çalışmalar var.

Uygulamamız ile ilgili ayrıntıları www.transsql.com alan adını taşıyan blog'umuzda bulabilirsiniz. Bu blog'taki yazılar hem Türkçe hem İngilizce. TransSQL konusundaki tüm gelişmeler orada yayınlanıyor.

Sitemizi ziyaret eder ve uygulamanın gelişimi konusunda bize yorumlarınız, tavsiyeleriniz ve yapıcı eleştirilerinizle destek gösterirseniz çok memnun oluruz.

Selamlar,
Ekrem Önsoy


1 Ağustos 2014 Cuma

Bir replikasyon macerası

Bugün bir replikasyon kurulumuyla başım beladaydı… Sizlere de anlatayım dedim.

SQL Server 2005 olan ortamların birinde sorun var diye haber geldi, bağlandım baktım, ne göreyim dersiniz? Error Log'da aşağıdaki kaydı gördüm:

The operating system returned error 23(Data error (cyclic redundancy check).) to SQL Server during a read at offset 0x00000000012000 in file 'C:\xxx\distribution.MDF'. Additional messages in the SQL Server error log and system event log may provide more detail. This is a severe system-level error condition that threatens database integrity and must be corrected immediately. Complete a full database consistency check (DBCC CHECKDB). This error can be caused by many factors; for more information, see SQL Server Books Online.

Tabii ki tüylerim diken diken oldu, çünkü bu, Corruption olduğu anlamına geliyordu.

Veritabanı SQL Server servis açılışında bu sorun nedeniyle yüklenemiyordu. Bu ortamdaki Distribution veritabanının bir yedeği de yoktu. Daha ne olsun? Kötü bir senaryo için her şeyimiz tam.

Neyse ki tatil dönemindeyiz ve neyse ki bu sunucuda sadece bir veritabanı replikasyona dahil.

Tüm replikasyonu kaldırıp, yapılandırmayı silip, her şeyi yeniden kurmaya karar verdim. Replike olan veritabanında aşağıdaki komutu çalıştırdım:

EXEC sp_removedbreplication

Daha sonra Distribution veritabanını kaldırmak için aşağıdakini:

EXEC sp_dropdistributor @no_checks = 1, @ignore_distributor = 1

Kar etti mi? Tabii ki hayır, çünkü Distribution veritabanım Corrupt durumda ve erişilemiyor. Bu noktada aklıma olan Distribution veritabanını kaldırmak ve yerine başka bir SQL Server 2005 Instance'ında yaratılmış Distribution veritabanını Restore etmek geldi, bunu yaptım.

Daha sonra Distribution veritabanını kaldırmak için aşağıdaki komutu çalıştırdım:

EXEC master.dbo.sp_serveroption @server=N'sunucu_adı', @optname=N'dist', @optvalue=N'true'

Bu komut hayatımı kurtardı. Sayesinde Distribution'dan kurtuldum ve replikasyonu tekrar baştan kurdum.

Burada benim hayatımı kurtaran şeyler, bağlanacak ve yalandan da olsa yeni bir Distribution veritabanı oluşturabilecek bir SQL Server 2005 ortamımın olması ve sp_removedbreplication ve sp_serveroption komutlarıydı.

Bir replikasyonu temizlemek zaman zaman gerçekten çok sıkıntılı olabiliyor, olur da birilerinin başına gelirse belki buradaki ipuçlarından faydalanabilirler…

Ekrem Önsoy

8 Temmuz 2014 Salı

Bir hikaye: Ahh şu yazılımcılar yok mu… Başımızın tatlı belaları!

Merhabalar,

Sanırım 1 ayı geçmiştir, özel bir firmadan, SQL Server ile ilgili olduğunu düşündükleri bir sıkıntı nedeniyle yardım çağrısı geldi. Durumun acil olduğunu söylediler ve ben de nasıl olduysa üşenmedim ve akşam 19.00 civarı gittim yanlarına. Size bu hikayeyi anlatmak istiyorum. Tabii ki beni arayan arkadaşımın ve şirketin bilgileri bende saklı.

Firmaya gittiğimde 2 arkadaş karşıladılar ve sorundan bahsettiler. Kullanmaya yeni başladıkları bir uygulama ile ilgili yavaşlık sorunu yaşıyorlardı, ama ne olduğunu bilen yoktu. Kullanıcı algısına göre önceki uygulamaları jet hızıyla çalışıyordu; fakat ne olduysa yeni uygulamaya geçtikten sonra birçok şey çok yavaşlamıştı, acaba sorun SQL Server olabilir miydi?

Durumu incelemeye başladık, Trace açtık, Log'ları inceledik… Bazı sorgular nispeten ağır çalışıyorlardı, Index'lerinin olmadığını gördük ve bunları oluşturduk; fakat en can alıcı şey, veritabanlarının AUTO_CLOSE özelliğinin ON oluşuydu. Üretim ortamlarındaki veritabanlarında neredeyse ASLA olmaması gereken bir durum. Bu bir 3. parti paket uygulama, yani başka bir şirket geliştirmiş. Muhtemelen o şirketteki yazılımcı arkadaşlar SQL kod geliştirme ortamı olarak SQL Server Developer Edition yerine SQL Server Express Edition kullanıyorlar. Çünkü AUTO_CLOSE özelliği Express Edition'larda varsayılan olarak ON!

Gerekli Index'leri oluşturduktan sonra ve en önemlisi de veritabanlarının AUTO_CLOSE özelliklerini ON yaptıktan sonra Pazartesi gününü bekledik ve kullanıcılar tarafından uygulamanın kabul edilebilir bir hızla çalıştığı bilgisini aldım.

Başka bir gün, yine aynı arkadaşlarımdan yine bir yardım çağrısı geldi ve ilk fırsatta uğradım yanlarına. Bu sefer sorun, belli ekranlarda yaşanan kayda değer bir yavaşlıkla ilgiliydi. Sorunu beraber inceledik ve bu sefer sorunun SQL Server ile hiçbir ilgisi yoktu. Sorun tamamen uygulama arayüzü tasarımı ile ilgiliydi. Şöyle ki, ekranda son kullanıcıya gösterilemek istenen veri SQL Server'dan 200 milisaniyede alınırken, arayüzde gösterilebilmesi 15-18 saniye sürüyordu! İnanabiliyor musunuz? Peki bu nasıl başarılabilmiş dersiniz? Uygulama arayüzünde bol bol Checkbox kullanarak böyle bir şey yapılabiliyor! Bu cümlemden Checkbox'ların ne kadar çok olduğunu ne kadar tahmin edebilirsiniz bilemiyorum, ama rahatça 50'den fazlaydı diyebilirim. Sorun tabii ki sadece Checkbox'lar da değildi, aynı zamanda Tab Control bileşeni de kullanılmış ve veritabanından yapılan sorgulama bu bileşendeki 10'dan fazla sekmedeki Datagridview'lere ve Checkbox'lara dağıtılıyor. Veriyi sorgulamak 200 milisaniye, ekranda gösterimi ise ortalama 17 saniye!

Aman yazılımcı arkadaşlarım, siz siz olun lütfen ekran tasarımını yabana atmayın. Tasarladığınız ekranlarda son kullanıcının yapabileceği veri girişini, veritabanındaki tablolarınızın tasarımını düşünerek kısıtlayın, iki tarafın da birbiriyle tutarlı olmasını sağlayın. Lütfen ama lütfen NULL olmaması gereken tablo alanları için veri girişi yapılan kullanıcı arayüzlerini NULL girilemeyecek şekilde tasarlayın ki sonra ISNULL veya COALESCE'lerle dolu sorgular görmeyelim ki sorgu performansımız kötü olmasın. Lütfen ekran tasarlarken yukarıdaki tecrübeyi de göz önünde bulundurun ki veritabanından 200 milisaniyede gelen sorgu için kullanıcılar 17 saniye beklemesin. Ekran tasarımı hakkında söylenebilecek daha nice şey var, ama akla ilk gelen en önemlileri bunlar.

Kolay gelsin,
Ekrem Önsoy

28 Haziran 2014 Cumartesi

TransSQL v1.0 BETA - Test çalışmaları 1. faz

Merhaba arkadaşlar,

Önceden "SQL Paket Taşıma Yöneticisi" adıyla sizlerle bazı haberlerini ve bazı özelliklerini paylaştığım çalışmamızın adını "TransSQL" olarak belirledik. Bu isimle SQL kodlarının Transfer edilmesi mesajını vermek istiyoruz. Transfer özü itibariyle Türkçe bir kelime olmasa da artık dilimize yerleşmiş, İngilizce de de kullanılan bir kelime.

www.transsql.com alan adını da almış durumdayız. Uygulama konusundaki çalışmalarımız yoğun bir şekilde devam ettiği için henüz site ile ilgilenemedik. Test çalışmaları belli bir noktaya geldikten sonra umuyorum ki internet sitemizi de devreye alacağız.

TransSQL, sıkı çalışmalarımız sonucu artık paket program haline geldi. Uygulamayı Türkçe ve İngilizceyi tam olarak destekleyecek hale getirmek istiyoruz, şu anda uygulama arayüzleri 2 dili destekliyor olsa da, dokümantasyon şimdilik sadece Türkçe. Zaman içinde bu noktadaki eksik de giderilecek ve uygulama artık yurtdışından arkadaşlar tarafından da kullanılabilecek.

Uygulama artık paket program durumuna geldiği için, başkalarının da test edebilmesi mümkün hale geldi. Eğer talip olanlarınız varsa lütfen benim gmail.com adresime bildirsin. Kendisine uygulamanın Setup'ının olduğu adresi vereceğim.

Test yapmak isteyenlerden ricam, lütfen:
- Karşılaşacağınız her olası sorunu not edin. Sorunla ne yaparken karşılaştınız; karşılaştığınız sorunun tam olarak tanımı, varsa hata mesajı nedir?
- "şu şöyle olsaydı çok daha iyi olurdu" diyebildiğiniz bir şey var mı?
- "şu da olsaydı çok daha iyi olurdu" diyebildiğiniz bir şey var mı?

Test ortamı gereksiniminiz:
- .Net 3.5 yüklü bir Windows OS (Client veya Server farketmez),
- SQL Server 2005 ve üstü versiyon, mümkünse Standard Edition ve üstü. Eğer bu, farklı bir makine olursa daha iyi; ama aynı makine de olsa sorun değil.

Desteğiniz için şimdiden çok teşekkürler!

Ekrem Önsoy

27 Haziran 2014 Cuma

Kerberos Configuration Manager for SQL Server

Merhaba!

Bugün günlük makaleleri okurken Kerberos Configuration Manager for SQL Server ile karşılaştım.

Daha sonra ilk defa 4-5 sene önce karşılaştığım aşağıdaki SQL Server Error Log mesajlarını hatırladım.

SQL Server is attempting to register a Service Principal Name (SPN) for the SQL Server service. Kerberos authentication will not be possible until a SPN is registered for the SQL Server service. This is an informational message. No user action is required.

The SQL Server Network Interface library could not register the Service Principal Name (SPN) [ MSSQLSvc/..com ] for the SQL Server service. Windows return code: 0x2098, state: 15. Failure to register a SPN might cause integrated authentication to use NTLM instead of Kerberos. This is an informational message. Further action is only required if Kerberos authentication is required by authentication policies and if the SPN has not been manually registered.

Bu mesajları ilk gördüğümüzde hemen SPN'in ne olduğunu internetten araştırmış ve öğrenmiştik. Akabinde Domain Administrator'ımızdan da SPN kayıtlarımızı yapmasını istemiştik.

Microsoft sonunda bu konu ile ilgili bir Tool üretmiş. Belki sizin de böyle bir ihtiyacınız olabilir diye paylaşmak istedim.

http://www.microsoft.com/en-us/download/details.aspx?id=39046

Kolay gelsin,
Ekrem Önsoy

18 Haziran 2014 Çarşamba

SQL Paket Taşıma Yöneticisi: Etkilenecek kayıt sayısı?



Merhaba!

SQL Paket Taşıma Yöneticisi uygulamasına beğeneceğinizi düşündüğüm bir özellik eklendi. Zaman zaman DELETE ve UPDATE gibi komutların çalıştırılması gerekiyor. Eğer bu komutu yazan siz değilseniz ve sadece çalıştırmanız gerekiyorsa, o zaman bu komutlar ile kaç tane kaydın etkileneceğini bilmeniz gerekir, ki buna göre bu komutu o anda çalıştırmanın uzun süreli Blocking'lere neden olmayacağından emin olasınız. Çoğu zaman da bu komutu çalıştırmanızı isteyen arkadaşlar, kaç kaydın etkileneceğini size söylemezler. Bu UPDATE ve DELETE komutlarını elle SELECT'lere çevirmek zorunda kalırsınız, aynı WHERE kriterlerini kullanarak kaç tane kaydın etkileneceğini görürsünüz. Örneğin:

Komutu yazan kişinin gönderdiği komut:
UPDATE dbo.tablo SET xxx = 'y' WHERE yyy='x'

Sizin bu komutu aşağıdaki gibi SELECT'e çevirip çalıştırmanız gerekir ki kaç tane kaydın etkileneceğini bilesiniz:
SELECT COUNT(*) FROM dbo.tablo WHERE yyy='x'

Elle taşıma yapmak zaten başlı başına tehlikeli bir iş iken, bir de böyle elle komutlar yazıp çalıştırmak durumu daha da tehlikeli bir hale sokar. Bazen UPDATE'e WHERE kriterinin eklenmesi unutulur ve tüm tablodaki kayıtlar değişiklikten etkilenir. Bu gibi durumların yaşandığını az çok tecrübesi olan herkes zaman zaman görüyor…

İşte yeni eklenen özellik tam da bu soruna parmak basıyor. Aşağıdaki ekran görüntüsünden de görebileceğiniz gibi paket girişi yapan kişi 2 UPDATE ve bir de DELETE komutu girmiş:

Resim1

Önceden de değindiğim gibi normal şartlar altında bu komutları çalıştırmadan önce SELECT'lerini tekrar yazmalı ve kaç kaydın etkileneceğini öğrenmeniz gerekirdi. Fakat SQL Paket Taşıma Yöneticisi'nin "Kayıt sayısını al" özelliği ile artık bu iş de otomatikleşmiş oluyor. "Kayıt sayısını al" düğmesine tıkladığınızda, betiğinizdeki tüm DELETE ve UPDATE komutlarının SELECT'leri otomatik olarak sizin için hazırlanıyor ve isteğinize göre çalıştırılıp kaç kayıt getirdikleri görülebiliyor. 

Resim2

Resim2'de görebileceğiniz gibi "Kayıt sayısını al" düğmesine tıklayınca aşağıda farklı bir bölüm daha açılıyor ve burada, betikteki tüm DELETE ve UPDATE komutları için otomatik olarak SELECT komutları yazılıyor. Olabilecek kritik ortamlar gözönüne alınarak bu işin kontrollü bir şekilde yapılması nedeniyle her SELECT komutunun yanına "Çalıştır" düğmeleri kondu. Her bir SELECT komutunu hemen yanındaki SELECT düğmesiyle çalıştırabilirsiniz. Bu komuttaki WHERE kriteriyle kaç kaydın etkilendiğini hemen düğmenin sağoldaki "Kayıt sayısı" bölümünde görebilirsiniz.

Bunun yanında, her bir SELECT komutunun betik içerisindeki hangi komuta ait olduğunu görmek için SELECT komutunun üstüne tıklayabilirsiniz. Resim2'de de görebileceğiniz gibi 2. SELECT komutuna tıkladığımda betik içerisindeki sonuncu satır da otomatik olarak işaretlendi.

Ekrem Önsoy

16 Haziran 2014 Pazartesi

SQL Paket Taşıma Yöneticisi ve havadisler

Selam!

Uzun zamandır Blog'uma giriş yapamadım. Özellikle son zamanlarda icat ettiğim 2 proje ile çok meşgulüm. Çok da haddim olmayarak, ama heyecanla 2 farklı uygulama geliştirme projesine bulaştım. Birisi bir arkadaşımın Cafe'si için hazırladığım sipariş alma uygulaması, diğeri de, ki bu sizleri de doğrudan ilgilendiriyor, SQL Server'a kod taşıma uygulaması. Bu projeleri yaparken SQL Server ile ilgili, küçük ama tatlı yeni şeyler de öğrendim, özellikle de 2. projede!

SQL Server'a kod taşıma ile ilgili olan projemden ayrıntılı olarak bahsedeceğim, ama önce öğrendiğim küçük de olsa yeni şeylere değinmek istiyorum.

İlk aklıma geleni, Database Mail ile eposta gönderirken yaşanılan 2 temel sorun ile ilgili. Birincisi, örneğin sp_send_dbmail ile birlikte @query parametresini kullandıysanız ve nvarchar(500) veritipi gibi veritipi olan bir alana sorgulama yapıyorsanız, gönderdiğiniz postanın içeriğinde bol bol ------ görürsünüz. Bundan kurtulmak için @query_result_header = 0 parametresiyle alan başlıklarını sorgulamamayı deneyebilirsiniz.

@query_result_header = 0 kullanarak ----'den kurtulsanız bile, eğer sorgunuz birden fazla kayıt getirecekse bu sefer de kayıtlar arasında 500 karakterlik boşluklar olacaktır. Bunu engellemek için de @query_resuld_no_padding = 1 parametresi gayet başarılı bir şekilde işe yarıyor!

sp_rename ile SP, Function, View gibi nesnelerin isimlerini değiştirdiğinizde sys.sql_modules Catalog View'ünde bu değişikliğin uygulanmadığını biliyor muydunuz? Ben bunu testlerim sırasında öğrenmiş oldum. Eğer sp_rename ile yapılan işlemler varsa, o zaman örneğin SP gibi bir nesnenin Create Script'ini sys.sql_modules'ten almaya kalktığınızda yanılmış olursunuz. Evet, belki 10 nesnenin 7'sinde sorun yaşamazsınız, fakat diğer 3'ü için kimse garanti veremez! Özellikle de çalışılan ortam çok sıkı denetimli bir ortam değilse. Microsoft da kendi dokümantasyonunda bir SP'nin adını değiştirmek için sp_rename'in kullanılmamasını, bunun yerine Script'in DROP + CREATE edilmesini öneriyor.

SQL Server'a kod taşıma uygulamama şimdilik verdiğim isim: SQL Paket Taşıma Yöneticisi. Bu uygulamaya birçok firmada gereksinim olduğunu ve piyasada bu işi yapabilecek doğru düzgün bir uygulamanın olmadığını gördüm. Denizbank'ta çalışırken orada Beamer adında, Intertech'te geliştirilen bir uygulamayı kullanıyorduk. Beamer birçok açıdan pratik bir uygulama. Fakat aynı zamanda küçük ve orta ölçekli firmaların alamayacağı kadar pahalı ve kullanamayacağı kadar kompleks bir uygulama. Beamer'ın satışı genelde bankalara yapılıyor bildiğim kadarıyla. Ben de hem piyasadaki açığı bildiğim için, hem de Beamer'ı, en azından Beamer'ın onay kısmını (hiç paket girişi yapmadım) 3,5 sene kullandığım için bu uygulamadan da esinlenerek "neden paçaları sıvayıp bir deneme yapmayayım ki?" dedim ve bu cürreti gösterdim.

Öncelikle SQL kodunun taşınması sırasında yaşanılan sıkıntılara biraz daha değinmek ve bu uygulamayı yapmamın nedenini biraz daha netleştirmek istiyorum. Küçük ve orta ölçekli firmalarda kod geliştirme işlemlerinin aşağı yukarı nasıl yapıldığını bu ortamlarda çalışıyor olan arkadaşlarım zaten biliyor. Bu ortamlarda genelde sadece bir tane Production SQL Server veritabanı oluyor ve yazılımcılar ya doğrudan geliştirme işlemlerini bu sunucuya RDP yaparak veya uzaktan SSMS ile bağlanarak yapıyorlar, ya da kendi bilgisayarlarında yaptıkları geliştirmeleri yine doğrudan SSMS ile herhangi bir denetime ve versiyonlamaya tabii olmadan yapıyorlar. Bunun neticesinde ne değişikliği geri almak için eski koda erişilmek istediğinde erişilebiliyor, ne taşımayı kimin, ne zaman yaptığı biliniyor, ne de kimin ne amaçla ne iş yaptığı biliniyor. Bu durum da hem güvenlik, hem performans, hem insan hatalarına zemin hazırlıyor.

İşte, SQL Paket Taşıma Yöneticisi bu yaralara çare olması için yapıldı! Ücretlendirilmesi ise küçük ve orta ölçekli şirketler için oldukça cazip olacak, çünkü uygulama özellikle de bu firmalar düşünülerek tasarlandı. Bunun yanında, uygulamanın büyük firmalarda da kullanılmaması için hiçbir sebep yok!

Geliştirme işlemleri ve testleri belli bir aşamaya geldiği için, yarından itibaren test işini birlikte çalıştığım yazılımcı arkadaşlarla yapmaya başlayacağız. SQL Paket Taşıma Yöneticisi'ni size aşağıda birkaç ekran görüntüsü ile tanıtmaya çalışacağım.

Şimdiki Beta versiyonda sizi aşağıdaki giriş ekranı karşılıyor:
Resim1: Giriş ekranı

Resim1'deki Sunucu adı bölümünde, kullanıcıları doğrulatmak istediğiniz sunucu adı bulunuyor. Kullanıcıların doğrulatılmak istenmesinin nedeni, uygulamayı kullanan kişilerin kim olduğunun bilinmesi gerektiği. Çünkü veritabanı değişiklikleri, bu kişilerin girdiği paketlerle yapılıyor olacak. Bunun için hangi kişisel bilgilerin gerektiğine başka bir ekranda tekrar değineceğim. Bu ekrandan temel olarak Windows Authentication veya SQL Authentication yöntemleriyle giriş yapılabilir.

Resim1'deki ekrandan giriş yapıldıktan sonra aşağıdaki ekranla karşılaşıyorsunuz:
Resim2: Paket girişi
Resim2'deki ekran, yazılımcıların paket girişi yapabilecekleri ekrandır. Bu ekrandan DELETE, UPDATE, INSERT, CREATE INDEX vb. işlemler için hem betik girişi yapılabilir, hem de SP, View, Trigger, Function, Table için nesne girişi yapılabilir. Nesne girişi ekranını Resim3'te göreceksiniz. Bu ekran temel olarak şöyle kullanılıyor. Önce sol üst köşede "Uygulama" kutusundan hangi uygulama işin taşıma yapacağınızı seçiyorsunuz. Daha sonra bu uygulamanın hangi ortamına taşıma yapmak istediğinizi, "Taşıma ortamı" kutusundan seçiyorsunuz. Bunların ne demek olduğuna "Uygulama yönetimi" sekmesinden bahsederken daha çok değineceğim. Bir sonraki seçiminiz ise "Taşıma tipi" olacak, ki buradaki Betik ve Nesne taşımalarına özetle yukarıda değindim. Aşağıda nesne ekleme ekranını görebilirsiniz. Bu ekranda, sol tarafta nesneleri görüyorsunuz. Bu nesneler gerçek zamanlı olarak, uygulamanızın (ki bu örnekte uygulama DrAdres uygulaması) test ortamına bağlanılıyor. Çünkü Taşıma ortamı olarak Test->Production seçilmiş. DrAdres uygulamasının test ortamı da yine ekran görüntüsünden görülebileceği gibi "localhost" isimli sunucudaki "test1" veritabanı.

Resim3: Paket girişi

"Taşıma nedeni"nde taşımayı neden yaptığınızı belirtiyorsunuz, bunun için "Proje" veya "Sorun giderme" seçeneklerini seçebilirsiniz. Daha sonra "Paket önceliği" seçeneğiyle paketinizin ne kadar öncelikle çalıştırılmasını beklediğinizi belirtiyorsunuz. Eğer bu adımı çalıştıracak olan yöneticiye bir notunuz varsa, bunu da "Kullanıcı notu"na girebilirsiniz. "Betik içeriği" kutusuna çalıştırmak istediğiniz kodu girin ve eğer hala oluşturmadıysanız "Paket oluştur" düğmesine basarak paketi oluşturun. Daha sonra bu adımı pakete eklemek için "Pakete ekle" düğmesine tıklayın ve bu adımı pakete eklemiş olun. Buradaki mantık şöyle, bir pakette birden fazla adım olabilir. Çünkü yaptıracağınız kod taşıma işlemindeki kodlar biribiriyle doğrudan bağlantılı olabilir ve bu bağlantıyı eposta veya telefonla anlatmak istemezsiniz. Eğer Resim2 ve Resim3'te göreceğiniz "Paket içeriği" düğmesine tıklarsanız, şimdiye kadar "Paket ekle" düğmesine tıklayarak yaptığınız işlemleri göreceksiniz.

Resim4: Paketin içeriği
Bu ekrandaki aşağı ve yukarı ok düğmeleriyle adımların hangi öncelikle çalıştırılacağını belirleyebilirsiniz. "Paketi kaydet" düğmesiyle artık bu paketle işinizin bittiğini ve yöneticinin paketi çalıştırması için hazır olduğunu belirtmiş olacaksınız. Bu noktaya kadar yönetici, bu giriş yaptığınız paketi görmüyordu. "Paketi kaydet" işlemiyle artık paket yöneticiye görünür hale gelecek. Eğer yanlışlıkla yaptığınız bir giriş varsa veya değiştirmek istediğiniz bir adım varsa o zaman "Paketten çıkar" düğmesine tıklayarak seçtiğiniz adımı paketten çıkarabilirsiniz. "Paketi iptal et" düğmesiyle de paketi komple silebilirsiniz.

Resim5: Paket onay

"Paket onay" sekmesini sadece "Paket girebilir" yetkisi olan yazılımcılar da görebilir. Fakat sadece kendi paketlerini görebilirler ve "Paketi aç" işlevini kullanamazlar. "Paketi düzenle" düğmesini kullanarak, yöneticinin onayına sundukları bu paketi yönetici onayından geri alarak tekrar "Paket girişi" sekmesine geri dönebilir ve paketin içindeki adımları tekrar düzenleyebilirler. "Paketin tarihçesi" düğmesi ile kendi paketlerine ait gelişmeleri görebilirler. Örneğin hangi paketteki hangi adımlar çalışmış, hangileri hata almış veya yönetici tarafından reddedilmiş… "Listeleme kriterleri"nden hangi paketlerin listeleneceği seçilebilir. Örneğin sadece çalıştırılanlar veya sadece çalıştırılacaklar veya paket numarasını bildiğiniz ve aradığınız bir paketi de buradan bulabilirsiniz!

Listeyi otomatik yenile kutusu daha ziyade yöneticiler için kullanılabilecek bir özellik. Bu sayede yöneticiler yazılımcıların girdikleri yeni paketleri fark edebilecekler. SQL Paket Taşıma Yöneticisi arka planda kalmış olsa da, Windows'un Görev Çubuğu'nda, saatin de bulunduğu sistem tepsisinde SQL Paket Taşıma Yöneticisi'nin simgesini göreceksiniz. Yeni bir paket geldiğinde bu sekmede yöneticiye "Onaylanacak … kadar paket var" diye bir hatırlatma balonu çıkacak. Bu özellikler sadece yöneticilere görünüyor.

Resim7: Hatırlatıcı


Resim7: Paketin içeriği
Yönetici bir paketi çalıştırmak istediğinde o paketi seçer ve "Paketi aç" düğmesine tıklar. Daha sonra karşısına Resim7'de de gösterildiği gibi paket içeriği çıkar. Yönetici, bu adımları yazılımcıların belirlediği sıraya göre çalıştırır. Farklı bir sırada çalıştırma şansı yoktur, yoksa uygulama tarafından uyarılır. Veya yönetici "Paketi reddet" düğmesiyle paketi komple reddedebilir. Bununla birlikte çalıştırılan adım eğer bir nesneye aitse (yani bir SP, View, Function vd. ise) ve hedef veritabanında bu nesneden daha önce varsa, adım çalıştırılmadan önce bu nesnenin hedefteki yedeği alınır. Bunun sayesinde bir sorun anında "Adımı geri al" düğmesi ile çalıştırılan adım geri alınabilir. Paketi çalıştırmak için "Adımı aç" düğmesine tıklanır ve aşağıdaki ekran açılır:

Resim8: Çalıştır

Betiklere ait paket çalıştırma ekranı Resim8'de gösterildiği gibidir. Aşağıda da nesnelere ait ekranı görebilirsiniz:

Resim9: Çalıştır

Bu ekrandaki kod pencerelerine yönetici doğrudan müdahale edemez. Yani ekranlardaki kodları değiştiremez. Fakat bazı durumlarda çalıştırılacak olan Script'teki komutun CREATE değil de ALTER olması istenebilir diye "ALTER'a çevir" diye bir seçenek eklendi. Bu seçenek kod içerisindeki tüm CREATE'leri tek tek bulur ve size hangisini değiştirmek istediğinizi sorar ve işlemi buna göre yapar. "Reddet" düğmesi ile sadece bu adımı reddedebilirsiniz. "Çalıştır" düğmesi ile kodu hedef veritabanına taşımış olacaksınız. Resim9'da gördüğünüz nesne taşıma ekranı her zaman bu şekilde çıkmayacak karşınıza. Örneğin bu adımı daha önceden çalıştırdıysanız veya hedef veritabanında bu nesneye ait bir örnek zaten varsa o zaman böyle 2 pencere şeklinde göreceksiniz. Soldaki pencere taşıyacağınız yeni kodu, sağdaki pencere ise yapacağınız seçime göre ve eğer varsa eski kodu veya hedefteki güncel kodu gösterecek.

Resim10: Uygulama yönetimi
"Uygulama yönetimi" ekranından, taşımasını yapacağınız uygulamalara ait ayrıntıları girebilirsiniz. Bu ekran sayesinde, sürekli sunucu adlarını, veritabanı adlarını hatırlamak ve aramak zorunda kalmazsınız. Bu ekrandan uygulamanız için uygulama adınızı, ortamını, kaynak sunucu ve veritabanını, hedef sunucu ve veritabanını bir kere belirlersiniz ve sonrasında "Paket girişi" sekmesinde sadece uygulama adını ve ortamını seçersiniz. Tüm bu ekranlar sıkı sıkıya birbirine entegredir.

Resim11: Kullanıcı yönetimi
"Kullanıcı yönetimi" ekranında kullanıcılarınıza ait bilgileri bulabilirsiniz. Buradaki bilgiler, paket girişini kimin yaptığı açısından önemli. Buradaki bilgileri sizin girmeniz şart değil. Bir kullanıcı SQL Paket Taşıma Yöneticisi'ni ilk kez kullanmak istediğinde kendisinden bu bilgileri girmesi rica edilecek. Bilgilerin girilmesi zorunlu değil, fakat her uygulamayı açılışında sorulacağı için sadece 3 satırlık bu bilgiyi girmek isteyecektir =) Ayrıca, buradaki eposta bilgisi kullanılarak, paketini onayladığınız kullanıcıya, paketiyle ilgili ayrıntılar eposta yoluyla aşağıdaki gibi gönderiliyor.

Resim12: eposta

Uygulama genel olarak böyle. "Genel olarak" diyorum, çünkü daha değinmediğim birçok ayrıntı var. Ayrıca bunun, uygulamanın sadece Beta v0.1 versiyonu olduğunu da hatırlatırım! Aklımda daha birçok şey var!

Lütfen yapıcı eleştirilerinizi ve önerilerinizi benden esirgemeyin.

Uzun bir aradan sonra, böyle uzun bir blog ile kendimi affettirmişimdir umarım.

Sevgiler!




3 Nisan 2014 Perşembe

Clustered Index Seek (Spatial): "Missing Column Statistics" ?!

Spatial veritiplerini ne kadar kullanıyorsunuz bilemiyorum, ama bizim 1-2 projemizde kullanılıyor ve bu nedenle Spatial Index'ler konusunda yüzeyselden öte biraz çalışma yapmam gerekti.

Aşağıdaki görüntüyü bir Execution Plan'da ilk defa gördüğümde şaşırmıştım, adını aşağıda paylaşacağım kitapta bunu gördüğümde o tecrübem aklıma geldi ve sizlerle de paylaşmak istedim.

Clustered Index Seek (Spatial)
Neden şaşırdığımı, Execution Plan'larla haşır neşir olan arkadaşlarım hemen anlayacaktır. Clustered Index Seek operatörü simgesinin üstünde bir de ünlem işareti vardı. Execution Plan'lardaki ünlem işaretleri, Execution Plan incelemelerinde ilk göze çarpan şeylerdendir. Tabii ki benim de hemen dikkatimi çekmişti ve fare ile bu operatörün üstüne gelip biraz beklediğimde (veya F4'e basıp Properties penceresindeki Warning alanında da görebilirsiniz) "Missing Column Statistics" uyarısını gördüm.

Bunu ilk gördüğümde, bunun gayet normal olduğunu bilmiyordum. Şöyle ki, geleneksel B-Tree Index'lerinin aksine, SQL Server, Spatial Index'lerin istatistiklerini Internal tablolarda tutuyor. Fakat maalesef Execution Plan oluşturulması işlemi sırasında bu dikkate alınmıyor ve biz de ilk gördüğümüzde bizi kaygılandıran bu uyarıyı görüp çırpınıyoruz.

Bu ve benzeri güzel bilgileri Pro Spatial with SQL Server isimli kitapta bulabilirsiniz! Özellikle SQL Server'da Spatial veritipleriyle çalışan arkadaşlarıma tavsiye ederim. En azından referans kaynak olarak elinizin altında bulunmasında fayda var.

Ekrem Önsoy


SQL Server 2012: Target Recovery Time

SQL Server 2014'ü incelerken farkettiğim, fakat aslında ilk defa SQL Server 2012 ile geldiğini öğrendiğim bir özellik, Target Recovery Time'a değinmek istiyorum.

SQL Server 2012'deki yeniliklerden bahsedilirken veya herhangi başka bir makalede hiç rastlamamıştım bu özelliğe. Bu özellik CHECKPOINT ile ilgili. Bu vesileyle SQL Server'daki Checkpoint'lere de değinmiş olayım.

Veritabanı moturunda veri sayfalarında yaptığı işlemleri RAM'de yapar (Data Cache'te) ve yaptığı her değişiklikten sonra hemen diske yazmaz bu değişiklikleri. Zaman zaman, aşağıda çeşitlerini açıkladığım gibi değişik Checkpoint tiplerini kullanarak yapar değişiklikleri diske yazma işlemini. Checkpoint işlemi, hafızadaki o anda bulunan (kirli sayfalar da denilen) veri sayfalarını ve Transaction Log bilgisini hafızadan diske yazma işlemidir. 

SQL Server'da 4 çeşit Checkpoint var, bunlar:
- Automatic: Otomatik Checkpoint'ler "EXEC sp_configure 'recovery interval', 'seconds'" ayarına bağlı olarak tetiklenir. Ayrıca veritabanı motoru yazma işlemlerindeki gecikme 20 milisaniyeyi geçtiğinde de bunu tetikler.
- Indirect: Bu, veritabanı bazında bir ayardır ve "ALTER DATABASE … SET TARGET_RECOVERY_TIME = target_recovery_time { SECONDS | MINUTES }" komutuyla belirlenir. Bu ayar, Instance düzeyinde belirlenen Automatic ayarı ezer. Varsayılan değeri 0'dır ve bu durumda diğer tipler işler.
- Manuel: Transaction SQL komutu olan CHECKPOINT komutu çalıştırılarak tetiklenebilir.
- Internal: Yedek alma veya veritabanı Snapshot'ı oluşturma gibi işlemlerde otomatik olarak veritabanı moturu tarafından tetiklenir. Bu tip için sizin müdahale etme şansınız yok.

Target Recovery Time özelliğini SQL Server Management Studio (SSMS) arayüzünden de değiştirebilirsiniz. Bunun için ilgili veritabanının özelliklerine gidip, Options sayfasındaki Recovery bölümünden aşağıdaki ekran görüntüsünde işaretlediğim ayarı değiştirmelisiniz. Örneğin bu ayarı 30 yaparsanız, her 30 saniyede bir veritabanınız için Checkpoint komutu çalıştırılacaktır ve Dirty Page'ler diske yazılacaktır. 

Bu komutu gerçekten ne yaptığınızı biliyorsanız kullanmanızı tavsiye ederim. Checkpoint işleminin her işlem gerçekleştiğinde tek tek değil de toplu toplu yapılmasının bir nedeni var, performans! Bu nedenle gerçekten ihtiyacınız olduğundan emin değilseniz Checkpoint işlemini bırakın SQL Server varsayılan ayarlarıyla halletsin.

SSMS: Target Recovery Time
Checkpoint'ler hakkında daha fazla bilgi için benim de bu yazıyı yazarken yararlandığım BOL sayfasını kullanabilirsiniz: http://msdn.microsoft.com/en-us/library/ms189573%28v=sql.120%29.aspx

Ekrem Önsoy

SQL Server 2014 - BPE ile ilgili bir BUG

Brent Ozar Buffer Pool Extension (BPE) kullanımıyla ilgili bir BUG tespit etmiş ve bunu dosyalamış. Bu konudaki gelişmeleri aşağıdaki Connect sayfasından takip edebilirsiniz.

https://connect.microsoft.com/SQLServer/feedback/details/844906/buffer-pool-extensions-fail-on-sql-server-restart

Ekrem Önsoy

2 Nisan 2014 Çarşamba

Yeni Cardinality Estimator

Bildiğiniz gibi dün, 1 Nisan'da SQL Server 2014 artık genel olarak kullanılabilir oldu ve Microsoft'un aşağıdaki adresinden indirilebilir:

http://technet.microsoft.com/en-US/evalcenter/dn205290

Yeni Cardinality Estimator hakkında biraz daha fazla yeni bilgi edinme şansım oldu, sizlerle de paylaşmak istedim.

Öncelikle, Cardinality Estimator nedir biraz onu anlatmaya çalışayım. Cardinality Estimation, SQL Server sorgu işlemcisi tarafından, Execution Plan oluşturulma işleminde kullanılır. Cardinality Estimate'ler nihai kayıt sayısı ve Join'ler, filtrelemeler ve SUM, COUNT gibi Aggregate işlemlerindeki kayıt sayılarının tahmininde kullanılır. Bu tahminler de yapılacak olan işlemler için oluşturulacak Execution Plan'ların seçimini belirler.

SQL Server 2014 öncesindeki SQL Server 2000, 2005, 2008, 2008R2 ve 2012 gibi versiyonlarda çoğu  kodu SQL Server 7.0'da yazılmış Cardinality Estimator kullanılıyordu; SQL Server 2014 ile birlikte isteğe bağlı olarak yeni, çağımızın iş yüklerine uygun olarak yazılmış Cardinality Estimator kullanılacak. İsteğe bağlı olarak dedim, çünkü bu yeni Cardinality Estimator'ı eğer veritabanının Compatibility Level'ını 120 yaparsanız veya 2312 numaralı Trace Flag'i kullanırsanız kullanabiliyorsunuz. Eğer veritabanınızın Compatibility Level'ı 120'den düşük ise ve 2312 numaralı Trace Flag'i de kullanmıyorsanız, o zaman yukarıda sıraladığım eski versiyonlarda varolan Cardinality Estimator'ı kullanıyor olacaksınız.

Eğer veritabanınızın Compability Level'ı 120 ise ve siz buna rağmen yine de eski Cardinality Estimator'ı kullanmak istiyorsanız o zaman da 9481 numaralı Trace Flag'i kullanmanız gerekiyor.

Eğer veritabanınızın Compatibility Level'ı 120 ise Execution Plan'ın 1. operatörünün Properties penceresindeki CardinalityEstimationModelVersion alanında 120 değerini göreceksiniz. Eğer ilgili veritabanının Compatibility Level'ı 120'den daha düşükse, o zaman bu alanda 70 değerini göreceksiniz. Bu da bence SQL Server 7.0'ye vurgu.

Bu Trace Flag'lerini sunucu, oturum veya sorgu düzeyinde kullanabilirsiniz. Ben şahsen, isterseniz ayıplayabilirsiniz, sorgu düzeyinde Trace Flag kullanılabildiğini bilmiyordum. Aşağıda bir örneğini veriyorum:

SELECT * FROM FactCurrencyRate WHERE DateKey = 20101201 OPTION (QUERYTRACEON 2312)

Compatibility Level'larını her değiştirdiğinizde ilgili veritabanı için Plan Cache'inizin de tamamen sıfırlanacağını hatırlamalısınız. Bu nedenle bu işlemi sık sık yapmak istemezsiniz.

Cardinality Estimator'un hangi versiyonunu kullanıyor olursanız kullanın, ama sonuç olarak Cardinality Estimator'lar için İstatistikler çok önemlidir. Bu nedenle İstatistiklerinizi olabildiğince güncel tutmanızda fayda büyük var. Auto Update Statistics ve Auto Create Statistics ayarlarının açık olduğundan emin olmalısınız. Index ve İstatistik bakımlarınızı düzenli olarak yapmalısınız. Cardinality Estimator'lar için bunlar çok kritiktir.


Yeni Cardinality Estimator'da, eskisinde olan tablo değişkenleriyle, TVF, TVP ve yerel değişkenlerle ilgili sorunların düzeltilmediği de belirtiliyor.


Bu yazı için yararlandığım kaynak: CSS SQL Server Engineers: SQL Server 2014’s new cardinality estimator (Part 1) 


Ekrem Önsoy

1 Nisan 2014 Salı

A connection was successfully established with the server, but then an error occurred during the login process. (provider: TCP Provider, error: 0 - The specified network name is no longer available.) (Microsoft SQL Server, Error: 64)

HATA:
SSMS'ten bağlanmaya çalıştığımda aldığım hata mesajı:
A connection was successfully established with the server, but then an error occurred during the login process. (provider: TCP Provider, error: 0 - The specified network name is no longer available.) (Microsoft SQL Server, Error: 64)

SQLCMD'den bağlanmaya çalıştığımda aldığım hata mesajı:
HResult 0x40, Level 16, State 1
TCP Provider: The specified network name is no longer available.

Sqlcmd: Error: Microsoft SQL Native Client : Communication link failure.

AÇIKLAMA:
Dün gece bir operatör bana bu hatayı haber verdi. Sorun yaşanan makineye X diyelim. Bu makine ile Y makinesi arasında Transactional Replication kurulu. Hem X'te Y'ye gönderilen bir Publication var, hem de Y'de, X'e gönderilen bir Publication var. Yani çift taraflı replikasyon söz konusu.

Öncelikle şunları kontrol ettim:
- X'ten Y'ye ve tam tersi yönde Ping atılabiliyor mu? Evet!
- X'ten Y'ye ve tam tersi yönde TELNET yapılabiliyor mu? Evet!
- X'e RDP yapmışken Y'ye SSMS ile bağlanabiliyor muyum? Hayır!
- Y'ye RDP yapmışken X'e SSMS ile bağlanabiliyor muyum? Evet!

- X'e RDP yapmışken Y'ye SQLCMD ile bağlanabiliyor muyum? Hayır!
- Y'ye RDP yapmışken X'e SQLCMD ile bağlanabiliyor muyum? Evet!
- X'e RDP yapmışken Y'ye ODBC Administrator'dan bir DSN oluşturup bağlanabiliyor muyum? Hayır!

- Y'ye RDP yapmışken X'e ODBC Administrator'dan bir DSN oluşturup bağlanabiliyor muyum? Evet!
- X'teki Windows Application Event Log'da ve SQL Error Log'da herhangi ilgili bir kayıt var mı? Yok!
- Y'deki Windows Application Event Log'da ve SQL Error Log'da herhangi ilgili bir kayıt var mı? Eğer yanlış kullanıcı bilgileri girersem, var! Eğer doğru kullanıcı bilgileriyle bağlanmaya çalışırsam, yok!
- İki sunucudaki Windows Firewall'ları kontrol ettim, kapalılar.
- Sistem ve Ağ yöneticileriyle konuştuk, bildiğimiz bir değişiklik yok dediler ve onlar da düşündü ve ortaya bir şey çıkmadı.
- X'te de Y'de de antivirüs uygulamaları kurulu, fakat uzun zamandır kuruluydular ve sorun dün akşam 19:00'dan itibaren olmaya başladı ve sistem yöneticilerinin söylediğine göre bu uygulamalarda SQL bağlantısını engelleyebilecek bir ayar da yok.
- Ağdaki diğer sunuculardaki SSMS ve SQLCMD'lerden Y'e bağlanmaya çalışıyorum, sorun yok. 
- Belli ki X'e özel bir durum söz konusu. X sunucusunu yeniden başlattık, fakat sorun çözülmedi.
- Son çare Google'a sordum. Bu sorun, çok genel bir sorun. Yani belli bir sorun değil. Herkes başka bir şey söylemiş ve hiçbiri de benim durumuma uymuyor.



ÇÖZÜM:
Son çare olarak Y sunucusunu yeniden başlatmayı gördük. Böyle garip durumlarda maalesef genelde yeniden başlatmak çözüm oluyor. Bizim durumumuzda da bu bir çözüm oldu. Fakat maalesef sorunun neden çıktığını, neden çözüldüğünü bilmiyor durumdayız. Bunu bu şekilde söylemek ve bu şekilde dokümante etmek canımı sıkıyor, ama olur ya belki bir gün birinin işine yarar...

Ekrem Önsoy

31 Mart 2014 Pazartesi

SSMS'te kişiselleştirilmiş ortam rengi kullanımı

Bu kullanımdan genelde bihaber olunduğunu düşünüyorum. Neden bahsettiğimi biraz daha açıklayayım, SQL Server Management Studio'nun 2008 versiyonuyla birlikte, "Connect to Server" penceresinde bağlandığımız ortam için renk seçimi yapabiliyoruz. Bu özellik, bağlandığımız ortamın ne kadar kritik bir ortam olduğunu bize görsel olarak da hatırlatıyor. Bazen, bazı ortamlarda o kadar çok SQL Server Instance'ı oluyor ve o kadar çok farklı Instance'a sürekli bağlanmamız gerekiyor ki, bazen feleğimiz şaşıyor ve nerede olduğumuzu karıştırıyoruz. Özellikle böyle ortamlar için bunun çok işe yarayabilecek bir özellik olduğunu düşünüyorum.

Aşağıdaki ekran görüntüsünde gördüğünüz Options >> düğmesine tıklayın.

Connect to Server penceresi
Aşağıdaki ekran görüntüsüyle karşılaşırsınız.

Connection Properties

Bu sekmede, yukarıda işaretlediğim alanı göreceksiniz. Eğer SQL Server Management Studio kullanarak bir SQL Server Instance'ına bağlanırken bu pencereden Select... düğmesine tıklayıp bir renk seçerseniz ve Use custom color kutucuğunu işaretlerseniz bağlandığınız SQL Server Instance'ı için hemen Query Editor penceresinin alt bölümündeki Status Bar aşağıdaki gibi renk değiştirecektir.


Tabii ki bu değişikliği Registered Servers penceresinde sakladığınız bağlantılar için de yapmanız bu özelliğin kullanımını pratikleştirecektir. Aksi takdirde her seferinde bu ayarı değiştirmeniz gerekir.

27 Mart 2014 Perşembe

Bir kaydın Data Cache'te olduğunu nasıl anlarsınız?

Belli bir veritabanındaki, belli bir tablodaki, belli bir kaydın Buffer Pool / Data Cache'te mi yoksa diskte mi olduğunu nasıl anlarsınız?

Öncelikle ilgilendiğiniz kaydın Page ID'sini bulmanız gerekiyor. Bunun için aşağıdaki gibi bir komut kullanabilirsiniz:

SELECT Teslim_Alan, sys.fn_physlocformatter(%%physloc%%) FROM dbo.tabloAdi WHERE xxx_No = 8071030185

Bu komutun sonucu aşağıdaki ekran görüntüsündeki gibi olacaktır:

İlgilendiğimiz kayıt ve Page bilgileri

sys.fn_physlocformatter(%%physloc%%) ile dönen veri bize ilgili kaydın fiziksel olarak nerede durduğunu gösteriyor. Açıklaması şöyle:

1 - Page'in bulunduğu dosyanın ID'si (File ID).
2 - Page ID
3 - Slot numarası

Artık elimizde ilgili kaydın gereken tüm fiziksel bilgileri var. Bu bilgileri kullanarak, önceki bir yazımda bahsettiğim gibi DBCC PAGE komutuyla ilgili Page hakkında daha fazla bilgiye de ulaşabilirsiniz, aşağıdaki DMV ile ilgili Page'in Data Cache'te olup olmadığını da kontrol edebilirsiniz.

SELECT * FROM sys.dm_os_buffer_descriptors WHERE page_id = 8867992 AND database_id = DB_ID()

Yukarıdaki komutu çalıştırdığınızda aşağıdaki gibi bir sonuç dönecektir:

İlgili Page'in Cache'te olup olmadığının sonucu
Eğer bir sonuç dönüyorsa, ilgili kayda ait Page, Cache'te demektir. Yani bu kayıt ile ilgili bir işlem yapmak istediğinizde, SQL Server diske gidip fiziksel IO yapmak zorunda kalmayacak, çok daha hızlı bir şekilde çalışabileceği RAM'e gidecek ve işlemi orada gerçekleştirecektir.

Not: sys.fn_physlocformatter(%%physloc%%) komutuna ait resmi Microsoft dokümanları bulamazsınız, çünkü Microsoft tarafından dokümante edilmemiş bir komuttur.

Ekrem Önsoy