Arama butonu
Bu konudaki kullanıcılar: 1 misafir
17
Cevap
5565
Tıklama
0
Öne Çıkarma
MSSQL ve c#
H
10 yıl
Yüzbaşı
Konu Sahibi

Merhaba arkadaşlar,
Multithread çalışan bir yazılım var. Sürekli (yaklaşık yarım dakika aralıklarla) veritabanı işlemleri yapıyorum(okuma yazma güncelleme vs..) Ortalama 400 adet thread ile çalışan bu yazılım birkaç gün sonra çöküyor. Sorgu sürelerini log'a yazdırıyorum. Ortalama 100ms sürüyo bir tanesinin sorgusu. Daha sonra ne oluyo bilmiyorum birden sorgular zaman aşımına uğramaya başlıyor. Aynı software üzerindeki tüm thread'lerin sorguları zaman aşımına uğrayınca tabi çöküyor.

Her bir sorgudan önce sql connection'ı açıp kapanıyorum. Timeout 3 dakika.

Sebebi ne olabilir acaba? Kodu gözden geçirdim kapatmadığım connection yok.

Hata :
System.Data.SqlClient.SqlException (0x80131904): Timeout süresi doldu. İşlem tamamlanmadan zaman aşımı süresi doldu veya sunucu yanıt vermiyor. 
The statement has been terminated. ---> System.ComponentModel.Win32Exception (0x80004005): Bekleme işlem zamanı aşıldı
konum: System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
konum: System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
konum: System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
konum: System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
konum: System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
konum: System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
konum: System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
konum: System.Data.SqlClient.SqlCommand.ExecuteNonQuery()



K
10 yıl
Yarbay

Sql de activity log a bak. Muhtemelen databaseye islem yaptigi sureden daha kisa surede sorgu geliyor. Yani sql bir requesti 1 sn de tamamliyorsa sen 400 request gonderirsen 400 sn boyunca hicbirsey gondermemen gerekir. Yoksa islemler kuyrukta bekler bekler. Sonunda beklerken timeout alirsin.

Bir de yazdigin sql lere execution plan dan bak belki hic ihtiyacin olmayan tableler cagiriyordur veya performans ve indexlerle ilgili sorunun vardir. Ve 400 farkli threadda islem yapacagina parallel querying olayina bak.



< Bu ileti mobil sürüm kullanılarak atıldı >
Bu mesaja 1 cevap geldi.
W
10 yıl
Yüzbaşı

veritabanında deadlock oluşuyor da olabilir. prosedür üzerinden set nocount on ile ado.net kullanabirsin ve bir de isolation level , with(nolock) komutlarını biraz araştır belki işine yarayabilir



C
10 yıl
Yüzbaşı

wqlky ye katılıyorum dead-lock oluşuyor olabilir şu makaleyi inceleyebilirsiniz
http://melikememis.wordpress.com/2012/05/14/lock-dead-lock/


Bu mesaja 1 cevap geldi.

Bu mesajda bahsedilenler: @hasan1980125
F
10 yıl
Yarbay

O programı kim yaptıysa git suratına çarp :) sp ve benzeri yapılar olmadan ust katmandan sorgu calısırsa olucagı budur.Bence database i yanlış kullanan sallama bir programdan dolayı göcüyor işlemlerin,milyonlarca istege karsılık verebilen serverler senin 400 sorguna cevap veremiyorsa hatanı programda ara derim...


Bu mesaja 2 cevap geldi.
H
10 yıl
Yüzbaşı
Konu Sahibi

Cevaplar için teşekkürler arkadaşlar,
@Kaygerya sorgu bitmeden diğer sorguya başlamıyorum. Yani kuyruktan bir veri çekiyorum ve veritabanı işlemleri yapıyorum. İşlemler bittiğinde bir sonraki veriye geçiyorum. İş hattı bu şekilde. Tabi multithread çalıştığı için diğerleri ile aynı anda sorgular yapıyor.
Parallel querying'e bakıcam.
@wqlky,@converttoint32 tamam beyler dead-lock olayını araştırayım biraz.
Elimden geldiğince optimize etmeye çalışıyorum fakat ne yalan söyleyim çok hakim değilim. Öğrenicez artık.
@fsh77 tamam yazıcıdan çıktı alıp yüzüne çarpıcam.



K
10 yıl
Yarbay

Her bir thread paralel olarak bir sorgu atiyor. Yani sql e 400 tane sorgu ayni anda geliyor (milisaniyelik farklar olabilir)

Hic baktin mi bir sorgun ne kadar surede geliyor.



< Bu ileti mobil sürüm kullanılarak atıldı >
Bu mesaja 1 cevap geldi.
H
10 yıl
Yüzbaşı
Konu Sahibi

Tekrar merhaba,
Response süreleri değişken bazen 100ms bazen 15-20ms.
Şuanda:
- Select komutlarına WITH(NOLOCK) eklendim.
- Yazılımda olması gereken yerlerde UPDATE'lere DEADLOCK_PRIORITY HIGH ayarladım.
- Tablonun index'lerini elden geçirdim
- Sorgu sırasında hata yakaladığımda Transaction'nını rollback yaptım. Command.Transaction.Rollback();

Benim sistemde thread'ler aynı tablo üzerinde çalışıyolar fakat her biri ID'sine göre farklı satırlarda update işlemleri yapıyor. Bu durum için başka ne gibi optimizasyonlar yapılabilir.

Bu arada dead-lock olayına bakmaya devam ediyorum. Şöyle bir göz gezdirilerek öğrenilecek gibi değil, baya derin bir mevzu.


Bu mesaja 1 cevap geldi.
M
10 yıl
Yüzbaşı

Benim öncelikli sorum neden 400 tane thread açıldığı olacaktır. Bu 400 thread 400 farklı yere mi bağlanıp sql update vs. yapıyor?


Bu mesaja 1 cevap geldi.
H
10 yıl
Yüzbaşı
Konu Sahibi

400 thread örnek olarak söylemiş arkadaş. Şuanda 2000 civarı bu adet.
Yazılım sunucu üzerinde çalışıyor (veritabanı da aynı sunucu üzerinde) ve farklı yerlerden bağlanan 400 adet client'ın isteklerine tek noktadan cevap veriyor.



K
10 yıl
Yarbay

Eh tamam iste parallel queyinge bakarsan sorunun cozulur. 2000 paralel threadin var islem yapan ama sqlin lineer calisiyor. Tamamiyle madness . Her thread gidiyor connection aciyor satiri buluyor update ediyor baglantiyi kapatiyor. Arada birsuru restrict gozden geciriliyor. Vay efendim bu kullanicinin buradan select atma yetkisi varmi update yetkisi var mi connectionu acayim mi sirada islem var mi varsa onu mu yapayim bunu mu vs...

No lock dedigin mevzu sadece onu mu yapayom bunu mu sorusuna derman olur.



< Bu ileti mobil sürüm kullanılarak atıldı >
Bu mesaja 1 cevap geldi.
H
10 yıl
Yüzbaşı
Konu Sahibi

Hocam max degree of parallelism'i 4'e getirdim. şuradan bakarak
Ama sorgulara ne ekleyeceğim anlamadım. Bu kendisi otomatik yapmıyordur heralde.
Client sayısı arttıkça lineer sorgu yaptığından response süreleri feci şekilde arttı. Bu paralel query olayını çözmem gerekli.
Bu dökümanı okudum. Senin tavsiye edebileceğin başka döküman var mı? Şu aşamadan sonra ne yapmam gerekiyor. Çok fazla kaynak yok açıkcası.


Bu mesaja 1 cevap geldi.
H
10 yıl
Yüzbaşı
Konu Sahibi

Tekrar merhaba,
Parallel quey uyguladım. Birden fazla deyim(update,insert vs..) içeren sorgularda hata yakaladığımıda transaction'ı rollback ettim. Açılıpta kapanmayan connection yok. Her bağlantıda kapatıldığında clearpool yaptım. Max Pool Size'ı ayarladım.
Şuanda her bir client'a ortalama 15ms'de cevap veriliyor. Bu kez farklı tablolardan aşağıdaki hatayı alıyorum.
Bu arada sql connection stringdeki timeout sorgunun mu yoksa bağlantının timeout süresi mi? Yani herhangibir şekilde bağlantı kapatılmadığında timeout bittiğinde bağlantı kapanacak anlamına geliyor değil mi?

System.Data.SqlClient.SqlException (0x80131904): Bağlantı Zaman Aşımı Doldu. Oturum açma öncesi el sıkışma bildirimini kullanmaya çalışırken zaman aşımı süresi doldu. Bunun nedeni oturum açma öncesi el sıkışmanın başarısız olması veya sunucunun zamanında yanıt verememesi olabilir.  Bu sunucuya bağlanmaya çalışırken harcanan süre - [Oturum Açma Öncesi] başlatma=5001; el sıkışma=10002;  ---> System.ComponentModel.Win32Exception (0x80004005): Bekleme işlem zamanı aşıldı 
konum: System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
konum: System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
konum: System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
konum: System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
konum: System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
konum: System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
konum: System.Data.SqlClient.SqlConnection.Open()



B
10 yıl
Yarbay

quote:

Orijinalden alıntı: fsh77

O programı kim yaptıysa git suratına çarp :) sp ve benzeri yapılar olmadan ust katmandan sorgu calısırsa olucagı budur.Bence database i yanlış kullanan sallama bir programdan dolayı göcüyor işlemlerin,milyonlarca istege karsılık verebilen serverler senin 400 sorguna cevap veremiyorsa hatanı programda ara derim...

Çok komiksin arkadaşım. Ms axapta hiç sp kullanmaz. Ben de şahsen kullanmam. Sp içinde yazacağım tüm kodu bir string içine koyar, öyle gönderirim.



< Bu ileti mobil sürüm kullanılarak atıldı >
Bu mesaja 1 cevap geldi.
F
10 yıl
Yarbay

O axapta, komik olan sensin sanırım axap daha ciddi geldi bana :)


Bu mesaja 1 cevap geldi.
H
10 yıl
Yüzbaşı
Konu Sahibi

Tekrar merhaba,
- Tablondan select ile verileri çeken sorguya
OPTION (QUERYTRACEON 8649,MAXDOP 0)
ekledim. Tablo üzerinde Key lookup işlemi maliyeti %73'den %60'a indi. Management studioda test ettim. Fakat c# da sorgu stringine ekleyince çalışmadı. Muhtemelen hata oluşuyo. Benim kodda web serviste olduğundan hata kodunu çıkaramadım. Başka bir şekilde derleyip hatanın ne olduğunu bulacam. Ama bilen varsa selam etsin.
- Şimdi, benim elimdeki tabloya daha öncede dediğim gibi thread'lerden sorgular geliyor(Update). Update işlemlerinde her thread kendi satırını güncelliyor. Bir thread kesinlikle başkasının satırına müdehale etmiyor. Normal şartlarda sql'in varsaydığı şekilde; Bir thread update işlemine başladığında tabloyu commit edene kadar kilitliyor. Diğer thread'ler commit edilmesini bekliyor. Burada hangi transaction-isolation-level uygun olur?

@Kaygerya
@wqlky




Bu mesajda bahsedilenler: @wqlky , @Kaygerya
K
10 yıl
Yarbay

Hocam parallel querying yaptiktan sonra thread acmana gerek yok. Tek threadin olacak o threaf sqldeki update islemini parallel yapacak.



< Bu ileti mobil sürüm kullanılarak atıldı >
Bu mesaja 1 cevap geldi.
H
10 yıl
Yüzbaşı
Konu Sahibi

Thread açmam lazım. Yoksa client'ları sırayla dinlemem lazım -ki buda çok büyük bir gecikmeye neden olur. Zaten işlem sıralı olsa sorgularda sıraya girmiş olur. her bir sorgu başlar biter ve diğerine geçer.
Benim amacım update işlemlerini aynı anda yapmak. Fakat bir update yapılırken tablo kilitleniyor ve diğerleri onu bekliyor. Bu beklemede katlanarak artıyor.
Max degree of paralellelism 4( standart versiyonda max 4 oluyormuş)
< Resime gitmek için tıklayın >

Bu arada senin bahsettiğin paralel sorgu ile bu parallelism aynı şey mi emin değilim. Parallelism sanki bana cpu maliyetini işlemler arasında dağıtan birşeymiş gibi geldi.
< Resime gitmek için tıklayın >



DH Mobil uygulaması ile devam edin. Mobil tarayıcınız ile mümkün olanların yanı sıra, birçok yeni ve faydalı özelliğe erişin. Gizle ve güncelleme çıkana kadar tekrar gösterme.