SQL Server'da yetersiz bellek veya yetersiz bellek sorunlarını giderme

Belirtiler

SQL Server, karmaşık ve zengin özellik kümesine karşılık gelen karmaşık bir bellek mimarisi kullanır. Çeşitli bellek gereksinimleri nedeniyle birçok bellek tüketimi ve bellek baskısı kaynağı olabilir ve sonuçta yetersiz bellek koşullarına neden olabilir.

SQL Server yetersiz belleği gösteren yaygın hatalar vardır. Hata örnekleri şunlardır:

  • 701: Sorguyu çalıştırmak için yeterli bellek ayrılamaması.
  • 802: Arabellek havuzundaki sayfaları (veri veya dizin sayfaları) ayırmak için bellek alınamaması.
  • 1204: Kilitler için bellek ayrılamaması.
  • 6322: XML ayrıştırıcısı için bellek ayrılamaması.
  • 6513:Bellek baskısı nedeniyle CLR başlatılamadı.
  • 6533: Bellek yetersiz olduğundan AppDomain kaldırıldı.
  • 8318: Yetersiz bellek nedeniyle SQL performans sayaçları yüklenemedi.
  • 8356 veya 8359: DÜŞÜK bellek nedeniyle ETW veya SQL izlemesi çalıştırılamıyor.
  • 8556: Yetersiz bellek nedeniyle MSDTC yüklenemedi.
  • 8645: Bellek atamaları için bellek olmadığından sorgu yürütülememesi (sıralama ve karma) Daha fazla bilgi için bkz. SQL Server hatası 8645 ile ilgili sorunları giderme.
  • 8902: DBCC yürütmesi sırasında bellek ayrılamaması.
  • 9695 veya 9696: Hizmet Aracısı işlemleri için bellek ayrılamaması.
  • 17131 veya 17132: Yetersiz bellek nedeniyle sunucu başlatma hatası.
  • 17890: sql belleği işletim sistemi tarafından diske alındığı için bellek ayrılamaması.
  • 22986 veya 22987: Yetersiz bellek nedeniyle veri yakalama hatalarını değiştirin.
  • 25601: Xevent altyapısının belleği yetersiz.
  • 26053: YETERSIZ bellek nedeniyle SQL ağ arabirimleri başlatılamıyor.
  • 30085, 30086, 30094: YETERSIZ bellek nedeniyle SQL tam metin işlemleri başarısız olur.

Neden

Birçok faktör yetersiz belleğe neden olabilir. Bu faktörler arasında işletim sistemi ayarları, fiziksel bellek kullanılabilirliği, SQL Server içinde bellek kullanan bileşenler ve geçerli iş yükündeki bellek sınırları yer alır. Çoğu durumda, bu hatanın nedeni bellek yetersiz hatasıyla başarısız olan sorgu değildir. Genel olarak, nedenler üç kategoride gruplandırılabilir:

Neden 1: Dış veya işletim sistemi bellek baskısı

Dış basınç, işlemin dışındaki bir bileşenden gelen ve SQL Server için yetersiz belleğe yol açan yüksek bellek kullanımını ifade eder. Sistemdeki diğer uygulamaların bellek kullanıp kullanmadiğini ve düşük bellek kullanılabilirliğine katkıda bulunup bulunmadiğini öğrenmeniz gerekir. SQL Server, bellek kullanımını geri alarak işletim sistemi bellek baskısına yanıt vermek için tasarlanmış çok az uygulamadan biridir. Başka bir deyişle, bir uygulama veya sürücü bellek isterse, işletim sistemi bellek boşaltmak için tüm uygulamalara bir sinyal gönderir ve SQL Server kendi bellek kullanımını azaltarak yanıt verir. Diğer birkaç uygulama bu bildirimi dinleyecek şekilde tasarlanmamış olduğundan yanıt verir. Bu nedenle, SQL Server bellek kullanımını kesmeye başlarsa, bellek havuzu azalır ve belleğe ihtiyaç duyan bileşenler onu alamayabilir. Sonuç olarak, 701 veya bellekle ilgili diğer hataları almaya başlarsınız. SQL'in belleği dinamik olarak ayırması ve boşaltması hakkında daha fazla bilgi için bkz. bellek mimarisini SQL Server. Sorunla ilgili daha ayrıntılı tanılama ve çözümler için bu makaledeki Dış bellek baskısı bölümüne bakın.

İşletim sistemi bellek baskısına neden olabilecek üç geniş sorun kategorisi vardır:

  • Uygulamayla ilgili sorunlar: Bir veya birden çok uygulama birlikte kullanılabilir fiziksel belleği tüketer. İşletim sistemi, biraz bellek boşaltmaya çalışarak kaynaklar için yeni uygulama isteklerine yanıt verir. Yaygın yaklaşım, belleği tüketen uygulamaları bulmak ve RAM tükenmesine yol açmadan aralarındaki belleği dengelemek için gerekli adımları atmaktır.
  • Cihaz sürücüsü sorunları: Sürücü bir bellek ayırma işlevini yanlış çağırırsa cihaz sürücüleri tüm işlemlerin çalışma kümesi disk belleğine neden olabilir.
  • İşletim sistemi ürün sorunları.

Bu ve sorun giderme adımlarının ayrıntılı açıklaması için bkz. MSSQLSERVER_17890.

Neden 2: İç bellek baskısı, SQL Server

İç bellek baskısı, SQL Server işleminin içindeki faktörlerin neden olduğu düşük bellek kullanılabilirliğini ifade eder. SQL Server işlemi içinde çalışabilen bazı bileşenler, SQL Server altyapısının "dış bileşenleridir". Bağlantılı sunucular, SQLCLR yordamları veya işlevleri, genişletilmiş yordamlar (XP'ler) ve OLE Otomasyonu (sp_OA*) gibi OLE DB sağlayıcıları (DLL' ler) bunlara örnek olarak verilebilir. Diğerleri, izleme amacıyla bir işlemin içine DLL'ler ekleyen virüsten koruma veya diğer güvenlik programlarını içerir. Bu bileşenlerin herhangi birinde bir sorun veya kötü tasarım büyük bellek tüketimine yol açabilir. Örneğin, bir dış kaynaktan 20 milyon veri satırını önbelleğe alarak SQL Server belleğe bağlı bir sunucu düşünün. SQL Server söz konusu olduğunda, hiçbir bellek katibi yüksek bellek kullanımını raporlamaz, ancak SQL Server işlemi içinde tüketilen bellek yüksek olacaktır. Örneğin bağlı sunucu DLL'sinden gelen bu bellek büyümesi, SQL Server bellek kullanımını kesmeye (yukarıya bakın) neden olur ve SQL Server içindeki bileşenler için yetersiz bellek koşulları oluşturarak yetersiz bellek hatalarına neden olur. Sorunla ilgili daha ayrıntılı tanılama ve çözümler için bkz. İç bellek baskısı, SQL Server gelmiyor.

Not

SQL Server işlem alanında kullanılan birkaç Microsoft DLL'leri (örneğin, MSOLEDBSQL, SQL Native Client), raporlama ve ayırma için SQL Server bellek altyapısıyla arabirim kurabiliyor. Bunların listesini almak ve bazı ayırmaları için bu bellek tüketimini izlemek için komutunu çalıştırabilirsiniz select * from sys.dm_os_memory_clerks where type='MEMORYCLERK_HOST' .

Neden 3: SQL Server bileşenlerden gelen iç bellek baskısı

SQL Server altyapısının içindeki bileşenlerden gelen iç bellek baskısı da yetersiz bellek hatalarına yol açabilir. SQL Server bellek ayıran bellek katipleri aracılığıyla izlenen yüzlerce bileşen vardır. Bu sorunu çözmek için en büyük bellek ayırmalarından hangi bellek katiplerinin sorumlu olduğunu belirlemeniz gerekir. Örneğin, bellek katibinin OBJECTSTORE_LOCK_MANAGER büyük bir bellek ayırma gösterdiğini fark ederseniz, Kilit Yöneticisi'nin neden bu kadar fazla bellek tükettığını anlamanız gerekir. Birçok kilit elde eden sorgular olduğunu fark edebilirsiniz. Dizinleri kullanarak, kilitleri uzun süre tutan işlemleri kısaltarak veya kilit yükseltmenin devre dışı bırakılıp bırakılmadığını denetleyerek bu sorguları iyileştirebilirsiniz. Her bellek katibi veya bileşeni, belleğe erişmek ve bunları kullanmak için benzersiz bir yönteme sahiptir. Daha fazla bilgi için bkz . bellek memuru türleri ve açıklamaları. Sorunla ilgili daha ayrıntılı tanılama ve çözümler için bkz. SQL Server altyapısına göre dahili bellek kullanımı.

Bellek baskı türlerinin görsel gösterimi

Aşağıdaki grafikte, SQL Server bellek yetersiz koşullarına yol açabilecek baskı türleri gösterilmektedir:

Bellek baskı türlerinin ekran görüntüsü.

Sorun giderme verilerini toplamak için tanılama araçları

Sorun giderme verilerini toplamak için aşağıdaki tanılama araçlarını kullanabilirsiniz:

Performans İzleyicisi

Performans İzleyicisi ile aşağıdaki sayaçları yapılandırın ve toplayın:

  • Bellek:Kullanılabilir MBytes
  • İşlem:Çalışma Kümesi
  • İşlem:Özel Baytlar
  • SQL Server:Memory Manager: (tüm sayaçlar)
  • SQL Server:Buffer Manager: (tüm sayaçlar)

DMV'ler veya DBCC MEMORYSTATUS

SQL Server içindeki genel bellek kullanımını gözlemlemek için sys.dm_os_memory_clerks veya DBCC MEMORYSTATUS kullanabilirsiniz.

SSMS'de Bellek Tüketimi Standart Raporu

bellek kullanımını SQL Server Management Studio görüntüleme:

  1. SQL Server Management Studio başlatın ve bir sunucuya bağlanın.
  2. Nesne Gezgini'da SQL Server örnek adına sağ tıklayın.
  3. Bağlam menüsünde RaporlarStandart Raporlar>>Bellek Tüketimi'ni seçin.

PSSDiag veya SQL LogScout

Bu veri noktalarını yakalamanın alternatif ve otomatik bir yolu , PSSDiag veya SQL LogScout gibi araçları kullanmaktır.

  • PSSDiag kullanıyorsanız, Perfmon toplayıcısını ve Özel Tanılama\SQL Bellek Hatası toplayıcısını yakalayacak şekilde yapılandırın.

  • SQL LogScout kullanıyorsanız Bellek senaryoyu yakalamak için yapılandırın.

Aşağıdaki bölümlerde her senaryo (dış veya iç bellek baskısı) için daha ayrıntılı adımlar açıklanmaktadır.

Sorun giderme metodolojisi

Zaman zaman veya kısa bir süre için bellek yetersiz hatası görünürse, kendisini çözen kısa süreli bir bellek sorunu olabilir. Bu durumlarda işlem yapmanız gerekmeyebilir. Ancak, hata birden çok bağlantıda birden çok kez oluşursa ve saniye veya daha uzun süre kalıcı olursa, bellek hatalarını daha fazla gidermek için aşağıdaki bölümlerde yer alan tanılamaları ve çözümleri izleyin.

Dış bellek baskısı

Sistemdeki düşük bellek koşullarını SQL Server işleminin dışında tanılamak için aşağıdaki yöntemleri kullanın:

  • Performans İzleyicisi sayaçlarını toplayın. Bu sayaçlara bakarak SQL Server dışındaki uygulamaların veya hizmetlerin bu sunucuda bellek tüketip tüketmediğini araştırın:

    • Bellek:Kullanılabilir MBytes
    • İşlem:Çalışma Kümesi
    • İşlem:Özel Baytlar

    PowerShell kullanarak Perfmon günlük toplama örneği aşağıda verilmiştir:

    clear
    $serverName = $env:COMPUTERNAME
    $Counters = @(
       ("\\$serverName" +"\Memory\Available MBytes"),
       ("\\$serverName" +"\Process(*)\Working Set"),
       ("\\$serverName" +"\Process(*)\Private Bytes")
    )
    
    Get-Counter -Counter $Counters -SampleInterval 2 -MaxSamples 1 | ForEach-Object  {
    $_.CounterSamples | ForEach-Object   {
       [pscustomobject]@{
          TimeStamp = $_.TimeStamp
          Path = $_.Path
          Value = ([Math]::Round($_.CookedValue, 3)) }
    }
    }
    
  • Sistem Olay günlüğünü gözden geçirin ve bellekle ilgili hataları (örneğin, düşük sanal bellek) arayın.

  • Uygulamayla ilgili bellek sorunları için Uygulama Olay günlüğünü gözden geçirin.

    Burada, "memory" anahtar sözcüğü için Sistem ve Uygulama Olay günlüklerini sorgulamaya yönelik bir PowerShell betiği örneği verilmiştir. Aramanız için "kaynak" gibi diğer dizeleri kullanmaktan çekinmeyin:

    Get-EventLog System -ComputerName "$env:COMPUTERNAME" -Message "*memory*"
    Get-EventLog Application -ComputerName "$env:COMPUTERNAME" -Message "*memory*"
    
  • Bellek kullanımını azaltmak için daha az kritik uygulamalar veya hizmetler için kod veya yapılandırma sorunlarını giderin.

  • SQL Server yanı sıra uygulamalar kaynakları kullanıyorsa, bu uygulamaları durdurmayı veya yeniden zamanlamasını deneyin ya da bunları ayrı bir sunucuda çalıştırmayı deneyin. Bu adımlar dış bellek baskısını ortadan kaldırır.

İç bellek baskısı, SQL Server

SQL Server içindeki modüllerin (DLL) neden olduğu iç bellek baskısını tanılamak için aşağıdaki yöntemleri kullanın:

  • SQL Server Bellekte Kilitli Sayfalar (AWE API' sini) kullanmıyorsa, belleğinin çoğu Performans İzleyicisi'daki Process:Private Bytes sayacına (SQLServrörnek) yansıtılır. SQL Server altyapısından gelen genel bellek kullanımı, SQL Server:Bellek Yöneticisi: Toplam Sunucu Belleği (KB) sayacına yansıtılır. Process:Private Bytes ve SQL Server:Memory Manager: Total Server Memory (KB) değeri arasında önemli bir fark bulursanız, bu fark büyük olasılıkla bir DLL'den geliyordur (bağlı sunucu, XP, SQLCLR vb.). Örneğin, Özel bayt 300 GB ve Toplam Sunucu Belleği 250 GB ise, işlemdeki toplam belleğin yaklaşık 50 GB'ı SQL Server altyapısının dışından gelir.

  • SQL Server Bellekte Kilitli Sayfalar (AWE API' sini) kullanıyorsa, Performans İzleyicisi tek işlemler için bellek kullanımını izleyen AWE sayaçları sunmadığından sorunu tanımlamak daha zordur. SQL Server altyapısındaki genel bellek kullanımı, SQL Server:Bellek Yöneticisi: Toplam Sunucu Belleği (KB) sayacına yansıtılır. Tipik İşlem:Özel Bayt değerleri genel olarak 300 MB ile 1-2 GB arasında değişebilir. Bu tipik kullanımın ötesinde önemli bir İşlem:Özel Bayt kullanımı bulursanız, fark büyük olasılıkla bir DLL'den (bağlı sunucu, XP, SQLCLR vb.) geliyordur. Örneğin, Özel bayt sayacı 4-5 GB ise ve SQL Server Bellekte Kilitli Sayfalar (AWE) kullanıyorsa, Özel baytların büyük bir bölümü SQL Server altyapısının dışından geliyor olabilir. Bu bir yaklaşıklık tekniğidir.

  • Görev Listesi yardımcı programını kullanarak SQL Server alanın içine yüklenen DLL'leri belirleyin:

    tasklist /M /FI "IMAGENAME eq sqlservr.exe"
    
  • Yüklenen modülleri (DLL) incelemek ve beklenmeyen bir şey olup olmadığını görmek için aşağıdaki sorguyu da kullanabilirsiniz.

    SELECT * FROM sys.dm_os_loaded_modules
    
  • Bağlı Sunucu modülünün önemli miktarda bellek tüketimine neden olduğundan şüpheleniyorsanız, İşleme izin ver seçeneğini devre dışı bırakarak bu modülü işlem dışı olacak şekilde yapılandırabilirsiniz. Daha fazla bilgi için bkz. Bağlı Sunucular Oluşturma . Tüm bağlı sunucu OLE DB sağlayıcılarının işlemi tükenmeyebilir. Daha fazla bilgi için ürün üreticisine başvurun.

  • OLE otomasyon nesnelerinin (sp_OA*) kullanıldığı nadir durumlarda, 4 bağlam değeri (yalnızca Yerel (.exe) OLE sunucusu belirterek nesneyi SQL Server dışında bir işlemde çalışacak şekilde yapılandırabilirsiniz. Daha fazla bilgi için bkz. sp_OACreate.

SQL Server altyapısı tarafından iç bellek kullanımı

SQL Server altyapısı içindeki bileşenlerden gelen iç bellek baskısını tanılamak için aşağıdaki yöntemleri kullanın:

  • SQL Server için Performans İzleyicisi sayaçları toplamaya başlayın: SQL Server:Buffer Manager ve SQL Server: Memory Manager.

  • Altyapıda en yüksek bellek tüketiminin nerede gerçekleştiğini görmek için SQL Server bellek katipleri DMV'sini birden çok kez sorgula:

    SELECT pages_kb, type, name, virtual_memory_committed_kb, awe_allocated_kb
    FROM sys.dm_os_memory_clerks
    ORDER BY pages_kb DESC
    
  • Alternatif olarak, bu hata iletilerini gördüğünüzde daha ayrıntılı DBCC MEMORYSTATUS çıkışı ve nasıl değiştiğini gözlemleyebilirsiniz.

    DBCC MEMORYSTATUS
    
  • Bellek katipleri arasında net bir suçlu tanımlarsanız, bu bileşen için bellek tüketimine ilişkin özellikleri ele alma konusunda odaklanın. Aşağıda birkaç örnek verilmiştir:

    • Bellek katibi MEMORYCLERK_SQLQERESERVATIONS bellek kullanıyorsa, büyük bellek atamaları kullanan sorguları belirleyin ve dizinler aracılığıyla iyileştirin, yeniden yazın (örneğin, kaldırın ORDER by) veya bellek verme sorgu ipuçlarını uygulayın (bkz . min_grant_percent ve max_grant_percent ipuçları ). Bellek verme belleği kullanımını denetlemek için bir kaynak yöneticisi havuzu da oluşturabilirsiniz . Bellek verme işlemleri hakkında ayrıntılı bilgi için bkz. SQL Server'de bellek atamalarının neden olduğu yavaş performans veya düşük bellek sorunlarını giderme.
    • Çok sayıda geçici sorgu planı önbelleğe alınırsa, CACHESTORE_SQLCP bellek katibi büyük miktarda bellek kullanır. Sorgu planları yeniden kullanılamayan parametrelenmemiş sorguları belirleyin ve saklı yordamlara dönüştürerek, kullanarak sp_executesqlveya parametreleştirme kullanarak FORCED bunları parametreleştirin. İzleme bayrağı 174'i etkinleştirdiyseniz, bunun sorunu çözip çözmediğini görmek için bu bayrağı devre dışı bırakabilirsiniz.
    • Nesne planı önbellek deposu CACHESTORE_OBJCP çok fazla bellek kullanıyorsa, hangi saklı yordamların, işlevlerin veya tetikleyicilerin büyük miktarda bellek kullandığını belirleyin ve uygulamayı yeniden tasarlayın. Genellikle, her birinde yüzlerce yordam bulunan büyük miktarda veritabanı veya şema nedeniyle bu durum oluşabilir.
    • OBJECTSTORE_LOCK_MANAGER Bellek katibi büyük bellek ayırmaları gösteriyorsa, birçok kilit uygulayan sorguları tanımlayın ve dizinleri kullanarak bunları iyileştirin. Kilitlerin belirli yalıtım düzeylerinde uzun süre serbest bırakılmamasına neden olan işlemleri kısaltın veya kilit yükseltmenin devre dışı bırakılıp bırakılmadığını denetleyin.
    • Çok büyük TokenAndPermUserStore ()select type, name, pages_kb from sys.dm_os_memory_clerks where name = 'TokenAndPermUserStore' gözlemlerseniz, önbelleğin boyutunu sınırlamak için izleme bayrağı 4618'i kullanabilirsiniz.
    • Bellek katibinden MEMORYCLERK_XTP gelen In-Memory OLTP ile ilgili bellek sorunlarını gözlemlerseniz, bellek yetersiz hataları için OLTP ve Bellek için iyileştirilmiş tempdb meta verileri (HkTempDB)In-Memory için Bellek Kullanımını İzleme ve Sorunlarını Giderme konusuna başvurabilirsiniz.

Belleği kullanılabilir hale getirebilecek hızlı rahatlama

Aşağıdaki eylemler biraz bellek boşaltabilir ve SQL Server kullanılabilir hale gelebilir:

Bellek yapılandırma ayarlarını değiştirme

Aşağıdaki SQL Server bellek yapılandırma parametrelerini denetleyin ve mümkünse maksimum sunucu belleğini artırmayı göz önünde bulundurun:

  • maksimum sunucu belleği
  • en az sunucu belleği

Not

Olağan dışı ayarlar fark ederseniz, bunları gerektiği gibi düzeltin ve artan bellek gereksinimlerini hesaba katın. Varsayılan ayarlar Sunucu belleği yapılandırma seçeneklerinde listelenir.

Özellikle Bellekteki Kilitli Sayfalar ile en yüksek sunucu belleğini yapılandırmadıysanız işletim sistemi için bellek sağlamak için bu belleği belirli bir değere ayarlamayı göz önünde bulundurun. Bellek sunucusu yapılandırmasında Kilitli Sayfalar seçeneğine bakın.

İş yükünü sistemden değiştirme veya taşıma

Sorgu iş yükünü araştırın: eşzamanlı oturum sayısı, şu anda yürütülen sorgular ve geçici olarak durdurulabilecek veya başka bir SQL Server taşınabilecek daha az kritik uygulama olup olmadığına bakın.

Salt okunur iş yükleri için, bunları Always On ortamındaki salt okunur ikincil çoğaltmaya taşımayı göz önünde bulundurun. Daha fazla bilgi için bkz. AlwaysOn kullanılabilirlik grubunun ikincil çoğaltmasına salt okunur iş yükünü boşaltma ve AlwaysOn kullanılabilirlik grubununikincil çoğaltmasına salt okunur erişimi yapılandırma.

Sanal makineler için uygun bellek yapılandırmasını sağlama

Sanal makinede (VM) SQL Server çalıştırıyorsanız, VM belleğinin fazla kaydedilmediğinden emin olun. VM'ler için belleği yapılandırma hakkında fikirler için bkz. Sanallaştırma - Belleği fazla kullanma ve VM içinde bellek algılama ve ESX/ESXi sanal makine performansı sorunlarını giderme (bellek fazla kullanımı).

belleği SQL Server içinde serbest bırakma

Birkaç SQL Server bellek önbelleğini boşaltmak için aşağıdaki DBCC komutlarından birini veya daha fazlasını çalıştırabilirsiniz:

  • DBCC FREESYSTEMCACHE

  • DBCC FREESESSIONCACHE

  • DBCC FREEPROCCACHE

SQL Server hizmetini yeniden başlatma

Bazı durumlarda, belleğin kritik tükenmesiyle ilgilenmeniz gerekiyorsa ve SQL Server sorguları işleyemiyorsa hizmeti yeniden başlatmayı düşünebilirsiniz.

Belirli senaryolar için Resource Governor kullanmayı göz önünde bulundurun

Resource Governor kullanıyorsanız kaynak havuzu ve iş yükü grubu ayarlarını denetledikten sonra belleği çok önemli ölçüde sınırlamadıklarını görmenizi öneririz.

Fiziksel veya sanal sunucuya daha fazla RAM ekleme

Sorun devam ederse, daha fazla araştırmanız ve muhtemelen sunucu kaynaklarını (RAM) artırmanız gerekir.