SQL Server DB gece boyunca kullanılamaz hale gelir


9

Dün, SQL Server veritabanım iyiydi. Bugün neredeyse kullanılamaz - vurduğum zamana bağlı olarak beş ila yirmi faktör arasında yavaşladı.

Bazı veriler sunucuya bir gecede yükleme işleminde eklenmiştir, ancak bir veritabanını çok fazla etkilemesi gereken bir birim gibi bir şey yoktur. Yaklaşık 50.000 düz metin kaydı (XML veya başka hiçbir kaygısız).

Biz yeniden başlatmadan önce sunucu bu sabah yamalı. Ancak, yamalanmış diğer veritabanı sunucularımızın hiçbiri farklı davranmamaktadır.

Kaynak Monitörü, disk IO'sunun hatalı olduğunu gösteriyor gibi görünüyor. Veritabanında gerçekte fazla bir şey olmasa bile, .mdf dosyasındaki kapasitenin% 100'ünde çalışıyor. Templog.ldf dosyasına erişim de oldukça yüksek.

Buradaki hiç kimse uzman bir DBA değildir (hepimiz değişen miktarda SQL becerisine sahip geliştiricileriz) ve hepimiz olanlardan şaşırdık. Sp_updatestats çalıştırmayı ve bazı büyük dizinleri farklı disklere taşımayı denedik.

Bunun yama ile ilgili bir şey olması gerektiğini düşünüyorum - çok fazla rastlantısal görünüyor. Bir meslektaş, mdf boyutunun yürütme planlarının verimsiz hale geldiği bir noktaya kadar artmasına neden olan veri yükü olduğuna ikna olmuştur.

Dünyada buna ne sebep oldu? Nasıl bulabiliriz ve düzeltmek için ne yapabiliriz?

DÜZENLE:

Kullanmak sp_WhoIsActiveolağandışı bir şey ortaya çıkarmaz. Şu anda başka bir endeksi taşımaya çalışan bir meslektaşından sproc ve bazı komutları kendi kullanımımı kaydediyor. Muhtemelen şu anda DB'yi elinde tutuyor, ancak daha önce olduğu kadar kötü çalışıyordu.

SQL Server 2008 R2'nin Standart sürümüdür. SELECT @@VERSIONverir:

Microsoft SQL Server 2008 R2 (SP2) - 10.50.4033.0 (X64)
9 Tem 2014 16:04:25
Telif Hakkı (c) Windows NT 6.1 üzerinde Microsoft Corporation Standard Edition (64 bit) (Derleme 7601: Service Pack 1) (Hipervizör) )

Sunucuda 72GB RAM ve üç adet dört çekirdekli 2GHz işlemci var.

Düzeltme eki yalnızca Windows'a uygulandı. Yamadan başka bir değişiklik olmadı.

Seçilen ayarlar:

_id     name                        value   minimum     maximum     value_in_use    description                                 is_dynamic  is_advanced
1540    min memory per query (KB)   1024    512         2147483647  1024            minimum memory per query (kBytes)           1           1
1541    query wait (s)              -1      -1          2147483647  -1              maximum time to wait for query memory (s)   1           1
1543    min server memory (MB)      0       0           2147483647  16              Minimum size of server memory (MB)          1           1
1544    max server memory (MB)      65536   16          2147483647  65536           Maximum size of server memory (MB)          1           1

GÜNCELLEME: Dizinleri ve tabloları farklı disk bölümlerine kaydırmak bazı şeyleri iyileştiriyor gibi görünüyor. Hala bu kadar sert sonuçlarla aniden bir devrilme noktasına nasıl ulaşacağımız konusunda kafam karıştı.


Sp_whoisactive'ı 5 dakika boyunca çalıştırabilir ve çıktıyı tabloya kaydedebilir misiniz? Buradan indirebilirsiniz ve bu tabloya nasıl çıktı alabileceğinizi gösterecektir
Kin Shah

Sunucuyu yeniden başlattıysanız, önbelleğe alınan tüm verilerinizin arabellek havuzundan atıldığı ve önbelleğe alınan tüm yürütme planlarınızın da atıldığı anlamına gelir. Bu, SQL Server'ın her ikisini de artırması gerektiği anlamına gelir - her yürütme planının yeniden derlenmesi gerekecektir ve istatistikler eskiyse en verimli planları alamayabilirsiniz. Ayrıca, verilerin diskten belleğe okunması gerektiği anlamına gelirken, yeniden başlatmadan önce muhtemelen bellekteki verilerle birlikte uğultu ediyordu. Bu kısa ömürlü olmalı.
Aaron Bertrand

@AaronBertrand Sekiz saattir böyle. Sunucuyu yama için düzenli olarak yeniden başlatıyoruz ve daha önce böyle bir şey fark etmedik.
Bob Tway

1
Yapılandırma ayarlarını kontrol etmek için kullanıcı arayüzünü kullanmayın. SELECT * FROM sys.configurations;- value, value_in_usegibi şeyler istiyorsun max server memory (MB). Ayrıca derleme numarası, SELECT @@VERSION;bunun bir hipervizörde olup olmadığı ve dünden beri (veya SQL Server'ın en son yeniden başlatılmasından bu yana) ana bilgisayarda bir şey değişip değişmediği de yararlı olacaktır.
Aaron Bertrand

2
Ne tür G / Ç alt sistemi kullanıyorsunuz? SAN, yerel disk vs. Tesadüfen kötü giden bir sürücünün olma şansı var mı? Ayrıca DB'leriniz herhangi bir işletim sistemi dosyasıyla aynı konumda mı depolanıyor? Ve son soru. İşletim sistemi yükseltmesi yapmadan önce sürecimizin bir kısmı önceden bir VM anlık görüntüsü almaktı. Ne yazık ki sorumlu kişi bunu yapmayı unuttu. Çok hızlı bir şekilde tüm sistem yavaşladı ve yavaşladı. Bunun sana olma ihtimali var mı?
Kenneth Fisher

Yanıtlar:


3

Küçük bir miktar veri, başka bir planı veya bunun gibi bir şeyi zorlamak için SQL Server'da belirli bir sınıra ulaşabilir. Bu pek olası değil. Ancak diskinizin ağır görev altında olduğu gerçeği beni başka bir sonuca götürüyor.

Yavaşlamanızın 2 olası nedeni vardır.

  1. Sisteminizi yükselttiniz ve yeniden başlattınız
  2. İçine bir sürü veri yüklersiniz

Bölüm 1'e bir bakalım.

SQL Server yapılandırmanız bozulmuş olabilir. Bu, Sunucu hızınız ve disk kullanımı ile ilgili ciddi sorunlara neden olabilir.

Lütfen ilk önce temel sunucu ayarlarınızı kontrol edin. Bunlar temel ayarlarıdır max server memory, affinity I/O mask, affinity maskve max degree of parallelism. Düğmesini kullanarak gelişmiş seçenekleri etkinleştirmeniz gerekebilir show advanced options.

İşte tam bir komut dosyası:

-- enable advanced options
EXEC sp_configure 'show advanced options',1
-- apply configuration
RECONFIGURE
-- how much memory can the sql server allocate?
EXEC sp_configure 'max server memory'
-- which cpu is used to run I/O operations
EXEC sp_configure 'affinity I/O mask'
-- which cpus can run processes?
EXEC sp_configure 'affinity mask'
-- how many threads can work on one query part?
EXEC sp_configure 'max degree of parallelism'

Kurulum adımlarınızda sonucu belgelenen değerlerinizle karşılaştırın. Hala aynı mı?

Sunucunuzun bu kadar tuhaf davranmasının birçok nedeni olabilir. Normalde bahse girerim, senin max server memoryyanlış olduğunu. Bu, SQL Server'ınızın veri sayfalarını kalıcı olarak değiştirmesine neden olur. Her şeyi hafızasında tutamaz. Bu, sayfaları diskten okuması, güncellemesi, anında geri yazması gerektiği anlamına gelir. Başka bir güncelleme gelirse ve bir güncelleme için aynı sayfayı kullanırsa, bellekten okunamaz. Bunun yerine sunucunun diskten tekrar okuması gerekir. Sadece değiştiriyorum ...

Başka bir sorun, disk veya işlemlerde yüksek bir afinite olabilir. SQL Server için ayrılmış bir diskle paylaşılan bir Sunucu (SQL Server + diğer hizmetler) kullandıysanız (bu nadir bir durum olabilir, ancak olabilir), bu sizin sorununuz olabilir. Sunucunuz normalde örneğin işlemler için 3 cpus ve G / Ç için bir tane olurdu. Diğer 12 cpus diğer hizmetler için kullanılır. Bu durumda yakınlık maskeniz yanlıştır ve örneğin otomatik bir yapılandırma kullanır. Bu, Sunucunuzun 16 çekirdeğin tamamını işlemler ve G / Ç için dinamik olarak kullandığı anlamına gelir. Çalışan büyük süreçleriniz varsa, diske büyük bir yük koyabilirler, bu disk işlemeyebilir. Ama aslında, bunun senin durumun olduğuna inanmıyorum. Bu geçerliyse (biraz da olsa) daha hızlı olurdu, ancak davanız yavaşlar.

Başka bir sorun çok yüksek bir paralellik derecesi olabilir. Bu, bir sorgunun bir kısmına rölantide çok fazla iş parçacığının olduğu anlamına gelir. Paralellik beklendiği gibi çalışmazsa bu da büyük bir yavaşlamaya neden olabilir. Ancak bu, toplamda yüksek I / O'nuzu tanımlamaz.

Şimdi 2. bölüme de bakalım

Sisteminize bir grup satır yüklersiniz. Bu normal bir iş olsa bile, sorgu planlarınızın arttığı bir sınır oluşturabilir. SQL Server ile birlikte eklemeniz bu davranışı üretir bile olabilir.

Endekslerinizi zaten yardımcı gibi görünen başka bir diske taşımaya çalıştığınızdan bahsettiniz. Bu, yükü iki farklı diske böltüğünüzde olabilir.

Endeksleriniz kırılmış, planlarınız kırılmış veya istatistikleriniz güncelliğini yitirmiş olabilir.

1. istatistiklerin son güncellemesini kontrol edelim Bunu, her bir istatistik elemanı için arayüz üzerinden manuel olarak yapabilirsiniz. Bu bir acı olur. Veya bu kodu deneyebilirsiniz:

SELECT name AS indexname,
STATS_DATE(OBJECT_ID, index_id) AS StatsUpdated
FROM sys.indexes

Bu, her bir dizin (ve yığın) ve bunların arkasındaki istatistikler hakkında tam bir bilgi verecektir. Çalıştırsanız bile sp_updatestats, istatistiklerin güncellendiği anlamına gelmez. Güncellemenin oldukça zor olduğu kısım, çalıştırsanız sp_updatestatsveya auto update statisticsetkinleştirilmiş olsa bile , istatistikler tam zamanında güncellenmez. Güncelleme gerektiğinde / oluşturulduğunda bazı kenar noktaları şunlardır:

  • Boş bir tablo bir veya daha fazla satır alır
  • 500'den fazla satırı olan bir tablo% 20 + 500 ek satırı günceller ve daha sonra bir ekleme yapıldı
  • 500'den az satır içeren bir tabloda 500 satır değiştirildiğinde

Bu, güncellemeyi çalıştırsanız bile istatistiklerinizin modası geçmiş olabileceği anlamına gelir.

Yukarıdaki sorguya bir göz atabilirsiniz. Bazı tablolarda bazı eski istatistikler bulursanız, bu tablo için manuel bir istatistik güncellemesi çalıştırmak isteyebilirsiniz:

UPDATE STATISTICS dbo.YourBadTable WITH FULLSCAN

Bundan sonra, tüm eski planları atmak için sunucunuza kıçından bir tekme vermek isteyebilirsiniz.

DBCC FREEPROCCACHE 

Yalnızca tüm önbellekleri temizlemek istiyorsanız, bunun yerine şunu çalıştırmak isteyebilirsiniz:

DBCC FREESYSTEMCACHE ('ALL')

Bu, yalnızca plan önbelleğini değil, tüm önbellekleri temizler. Normalde bunu üretim aşamasında bir üretim sunucusunda kullanmak için uyarırdım. Ancak sunucunuz şu anda çalışmadığından, onlara çok fazla zarar veremezsiniz. Tüm önbellekleri yeniden oluşturması gerektiğinden birkaç saniye belki 1-2 dakika yavaşlayabilir, ancak bundan sonra doğru planlarla koşmalıdır.

Başka bir neden tamamen parçalanmış endeksler olabilir. Bu, aşağıdaki ifadeyi kullanarak tüm sunucuda kontrol edilebilir:

SELECT * 
FROM sys.dm_db_index_physical_stats (NULL, NULL, NULL, NULL, NULL)

Parçalanma çok yüksekse, yeniden organize etmeniz (parçalanma <% 20) veya tamamen yeniden oluşturmanız (>% 20) gerekebilir. Bu, disk üzerinde daha fazla baskı oluşturabilir ve soruna neden olabilir. Öte yandan, eğer endeksler bu kadar kötü ise, muhtemelen sonunda zarardan daha fazla yardımcı olacaktır.

Bu iki nedenin yanında, yine de üçüncü bir sorun olabilir

Sunucunuz muhtemelen yapılandırılmış olabilir, şu anda herhangi bir kodu değiştirmediniz, sadece birkaç satır eklediniz. Tüm istatistikler güncellenir ve tüm önbellekler yeniden oluşturulur. Tüm endeksleriniz onlara ihtiyaç duyduğunuz şekilde yeniden düzenlenir, ancak yine de - hiçbir şey işe yaramaz. Sadece işlemlerinizde kullanılabilir bellek sınırına ulaşmış olabilirsiniz. Belki daha fazlasına ihtiyacınız vardır. Sizden daha fazla bellek almaya çalışan herhangi bir işlem olup olmadığını kontrol edebilirsiniz.

Bu komutu kullanarak bunu kontrol edebilirsiniz:

SELECT * FROM sys.dm_exec_query_memory_grants

Hafıza tüketen tüm oturumların bir listesini sağlayacaktır. Hala bellek almak için bekleyen bazı sorgu olabilir. Bu sorgular kolayca filtrelenebilir. Tüm oturumlar nerede granted_memory_kb IS NULL. Bunlar, bellek isteyen ancak almayan oturumlardır. Başka bir şey, düşük olabilecek bir hafıza olabilir. Sütunları requested_memory_kbile karşılaştırabilirsiniz granted_memory_kb. İstenen, işlemin en iyi şekilde çalışması için gereken bellek miktarını gösterirken, verilen işlem için etkinleştirilen belleği gösterir. Bir işlemin çalışması için 2 GB gerekiyorsa ancak yalnızca 2 MB alırsa ... kendi başınıza alabilirsiniz. ;-)

Başka bir yol da aşağıdakileri kontrol etmektir RESSOURCE_SEMAPHORE:

SELECT * FROM sys.dm_exec_query_resource_semaphore

Sen bir göz alabilir waiter_countve grantee_count. Eğer garson 0'ın üzerindeyse, hafızanızda, swapping'e neden olabilen ve perfmonda gördüğünüz disk basıncına neden olabilecek bir baskı vardır.


0

Olası sürücü arızalarına ek olarak, RAID alt sisteminizin durumunu kontrol edin. Benzer bir şey gördük ve RAID denetleyicisindeki pilin başarısız olduğu ortaya çıktı, bu nedenle yazma önbelleği yoktu - tüm yazma işlemleri doğrudan diske gitmek zorunda kaldı. Bir yan not - RDC'ye girerken sistemin durakladığını hissedebiliyorduk.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.