SQL Server'ı yeniden başlatmak dışında, SQLCLR AppDomain'i sıfırlamaya zorlamanın bir yolu var mı?


11

SQLCLR tarafından kullanılan AppDomain sıfırlamak için zorlamak istiyorum. SQL Server örneğini yeniden başlatmanın yanı sıra bunu nasıl yapabilirim?


Yanıt güncellemeleri hakkında bildirim alıp almadığınızdan emin değilim, ancak cevabımı daha kolay bir yöntemle güncelledim :).
Solomon Rutzky

Yanıtlar:


6

Bunun biraz acımasız olduğunu biliyorum, ama CLR'yi devre dışı bırakıp yeniden etkinleştirmeye ne dersiniz?

sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'clr enabled', 0;
GO
RECONFIGURE;
GO
sp_configure 'clr enabled', 1;
GO
RECONFIGURE;
GO

2
Bu yöntemle ilgili önemli bir ayrıntı, bir STANDBY (salt okunur) veritabanına karşı yürütüldüğünde çalışmasıdır; denediğim diğer tüm yöntemler kullanmayın. Bir STRBY kataloğuna günlük nakliye yoluyla normal olarak yayılan bir CLR derleme için bir güncelleme, ancak AppDomain yeniden --- --- bu yüzden yaklaşık bir gün için .dll eski sürümünden kodu çalışmaya devam çünkü buna ihtiyacım vardı.
Granger

@Granger çok ilginç ve bilmek güzel :). Ancak, SQL Server içinde bir hata düşünün. Connect sitesi üzerinden bunu bildirmek isteyebilirsiniz: connect.microsoft.com/SQLServer/Feedback
Solomon Rutzky

1
@srutzky - Öneri için teşekkürler; Raporu "Düzeltilmeyecek" olarak kapatacaklarını umuyorum. Ayar, sunucu başına yapılır, katalog başına değil (tıpkı 'iç içe tetikleyiciler', 'dosya akışı erişim düzeyi' vb.). Bu açmaya çalışacağım solucanlar olabilir.
Granger

@Granger (ve Max): Bir hata olduğunu düşündüğümü söylediklerim net değildi. Ben kaldırma neden "CLR Etkin" ayarını sıfırlama bir hata olduğunu söylemiyordum. ALTER ASSEMBLYUygulama etki alanını yeniden yüklemeyen (veya en azından boşaltma) olmayan günlük gönderimi yoluyla yayılanın hata olduğunu söylüyordum . Her iki durumda da, cevabımı buraya eklediğim daha kolay bir yöntem buldum. Açıkladığınız günlük nakliye senaryosunda çalışıp çalışmadığını görmek için çok merak ediyorum, bu yeni yöntemi test etme yeteneğiniz varsa.
Solomon Rutzky

8

Diğer tüm derlemeleri etkilemeyecek daha zarif bir çözüm var: Uygulama etki alanındaki derlemelerden birinin PERMISSION_SET'ini değiştirin (uygulama alanları kullanıcı başınadır).

ALTER ASSEMBLY [AssemblyName] WITH PERMISSION_SET = {1 of the 2 levels that 
                                                      this assembly is not current at}

PERMISSION_SET değerini eski haline döndürmeniz gerektiğini unutmayın. Ayrıca, PERMISSION_SET değiştirmeden önce derlemedeki bir yönteme erişmeniz gerekir; şu anda etkin olan bir uygulama etki alanına yüklenmemiş ancak başka bir derlemeyle birlikte bir derlemenin uygulama etki alanı üzerinde hiçbir etkisi yoktur (Uygulama Etki Alanları, Derleme başına değil, Kullanıcı Başına DB'dir, Kullanıcı Başınadır).


GÜNCELLEME
Yukarıda açıklanan yöntem, yalnızca bir Uygulama Alanını kaldıracağı en ince yaklaşımdır. Ancak, montajın diğer iki seviyeden birine ayarlanabilmesi gerekir. İşaretli montajlar SAFEiçin ancak

  • veritabanı TRUSTWORTHY ON, veya
  • montaj imzalı ve montaj ile aynı imzaya dayalı kendisini bir asimetrik anahtar dayalı bir Girişi, mevcut ve ya verilmiş olan EXTERNAL ACCESS ASSEMBLYveya UNSAFE ASSEMBLYizin

Bu durumda, TRUSTWORTHYayarı basitçe ONdöndürebilir OFFve hemen geri dönebilirsiniz ; bu, söz konusu veritabanındaki tüm Uygulama Alanlarını kaldırır:

ALTER DATABASE CURRENT SET TRUSTWORTHY ON;
ALTER DATABASE CURRENT SET TRUSTWORTHY OFF;

Yine de veritabanında yalnızca bir Uygulama Etki Alanı varsa (ve bunun zamanın% 95'i veya daha fazlası olduğundan şüpheleniyorsanız), burada açıklanan yöntemlerin her ikisi de aynı net etkiye sahiptir. Ve bu durumda, ALTER DATABASEyöntem , belirli bir nesne adı belirtmeyi gerektirmediği veya orijinalin ne olduğunu bilmeyi gerektirmediği için daha basit görünüyor PERMISSION_SET.

AYRICA, yalnızca tek bir Uygulama Etki Alanınız varsa, ALTER DATABASEveritabanının önceden ayarlanmış olması durumunda TRUSTWORTHY ONveya anahtar tabanlı oturum açmayı uygun izinle ayarlamış olsanız bile yöntem daha basittir . Eğer bir anahtar tabanlı giriş kullanıyorsanız o zaman ayarlayabilirsiniz TRUSTWORTHYiçin ONve daha sonra OFFtekrar yukarıda belirtilen. Ancak, zaten TRUSTWORTHYayarladıysanız ON, tersine çevirin ve OFFhemen ve sonra hemen geri ayarlayın ON:

ALTER DATABASE CURRENT SET TRUSTWORTHY OFF;
ALTER DATABASE CURRENT SET TRUSTWORTHY ON;

1
Güncellenmiş bir yaklaşım çalışır a STANDBY (READ_ONLY) veritabanı katalogunda. Sql Server "TRUSTWORTHY" ayarını değiştirmeme izin verdi, sonra önceki haline geri yükledi. Sonucuna bakarak değişikliğin aslında alan adını kaldırdığını doğruladım SELECT * FROM sys.dm_clr_appdomains;. Tatlı.
Granger
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.