Selain me-restart SQL Server, apakah ada cara untuk memaksa SQLCLR AppDomain diatur ulang?

11

Saya ingin memaksa AppDomain yang digunakan oleh SQLCLR untuk diatur ulang. Bagaimana saya bisa melakukan itu selain memulai kembali contoh SQL Server?

Justin Dearing
sumber
Tidak yakin apakah Anda mendapat pemberitahuan tentang pembaruan jawaban, tetapi saya memperbarui jawaban saya dengan metode yang lebih mudah :).
Solomon Rutzky

Jawaban:

6

Saya tahu ini agak brutal, tetapi bagaimana dengan menonaktifkan CLR dan mengaktifkannya kembali?

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
Max Vernon
sumber
2
Satu detail penting tentang metode ini adalah bahwa ia berfungsi ketika dieksekusi terhadap database STANDBY (hanya baca); semua metode lain yang saya coba lakukan tidak. Saya memerlukan ini karena pembaruan untuk perakitan CLR diperbanyak seperti biasa melalui pengiriman log ke katalog STANDBY, tetapi AppDomain tidak dimuat ulang --- jadi terus menjalankan kode dari versi lama .dll selama sekitar satu hari.
Granger
@Granger sangat menarik dan senang tahu :). Namun, saya akan mempertimbangkan bahwa bug dalam SQL Server. Anda mungkin ingin melaporkannya melalui situs Connect: connect.microsoft.com/SQLServer/Feedback
Solomon Rutzky
1
@srutzky - Terima kasih atas sarannya; Saya berharap mereka hanya akan menutup laporan sebagai "Tidak akan diperbaiki". Pengaturan ini mencakup seluruh server, bukan per-katalog (seperti 'pemicu bersarang', 'tingkat akses filestream', dll.). Itu cukup kaleng cacing yang akan aku coba buka.
Granger
@ Granger (dan Max): Saya tidak jelas tentang apa yang saya katakan saya pikir adalah bug. Saya tidak mengatakan bahwa mereset pengaturan "CLR Enabled" menyebabkan pembongkaran adalah bug. Saya mengatakan bahwa ALTER ASSEMBLYdiperbanyak melalui pengiriman log yang tidak memuat ulang (atau setidaknya membongkar) App Domain adalah bug. Either way, saya menemukan metode yang lebih mudah yang saya tambahkan ke jawaban saya di sini. Jika Anda memiliki kemampuan untuk menguji metode baru ini, itu akan menjadi hebat karena saya sangat ingin tahu apakah itu berfungsi dalam skenario pengiriman log yang Anda jelaskan.
Solomon Rutzky
8

Ada solusi yang lebih elegan yang tidak akan memengaruhi semua majelis lain: cukup ubah PERMISSION_SET dari salah satu majelis dalam domain aplikasi (domain aplikasi adalah per pengguna).

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

Ingatlah bahwa Anda perlu mengatur PERMISSION_SET kembali ke seperti semula. Selain itu, Anda perlu mengakses metode dalam perakitan sebelum mengubah PERMISSION_SET akan membongkar itu; mengubah rakitan yang saat ini tidak dimuat ke domain aplikasi yang aktif, tetapi dengan rakitan lain, tidak berpengaruh pada domain aplikasi (Domain Aplikasi adalah per-DB, per-Pengguna, bukan per-Majelis).


PEMBARUAN
Metode yang dijelaskan di atas adalah pendekatan yang paling tepat di mana ia hanya akan membongkar satu Domain Aplikasi itu. Tapi, itu memang mengharuskan perakitan dapat diatur ke salah satu dari dua level lainnya. Untuk majelis yang ditandai karena SAFEhanya akan dimungkinkan jika salah satunya

  • database diatur ke TRUSTWORTHY ON, atau
  • majelis ditandatangani dan Login, didasarkan pada kunci asimetris yang dengan sendirinya didasarkan pada tanda tangan yang sama dengan majelis, ada dan telah diberikan salah satu EXTERNAL ACCESS ASSEMBLYatau UNSAFE ASSEMBLYizin

Dalam hal ini Anda dapat dengan mudah mengubah TRUSTWORTHYpengaturan ONdan kemudian segera kembali OFFlagi dan itu akan membongkar semua Domain Aplikasi dalam database tertentu:

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

Jika Anda hanya memiliki satu App Domain dalam basis data (dan saya kira ini adalah kasus 95%, atau lebih, pada saat itu), maka kedua metode yang dijelaskan di sini memiliki efek bersih yang sama. Dan dalam situasi itu, ALTER DATABASEmetode ini tampak lebih sederhana karena tidak memerlukan menentukan nama objek tertentu juga tidak perlu mengetahui apa yang asli PERMISSION_SET.

JUGA, jika Anda hanya memiliki satu App Domain maka ALTER DATABASEmetodenya lebih sederhana bahkan dalam kasus di mana database sudah diatur TRUSTWORTHY ONatau Anda telah mengatur login basis-kunci dengan izin yang sesuai. Jika Anda menggunakan login berbasis kunci maka Anda dapat mengatur TRUSTWORTHYke ONdan kemudian OFFlagi seperti yang disebutkan di atas. Tetapi jika Anda sudah TRUSTWORTHYmenyetel ke ON, maka balikkan dan atur ke OFFlalu segera kembali ke ON:

ALTER DATABASE CURRENT SET TRUSTWORTHY OFF;
ALTER DATABASE CURRENT SET TRUSTWORTHY ON;
Solomon Rutzky
sumber
1
Pendekatan yang diperbarui bekerja pada katalog database STANDBY (READ_ONLY). Sql Server mengizinkan saya untuk mengubah pengaturan "TRUSTWORTHY", lalu mengembalikannya ke keadaan semula. Saya memverifikasi bahwa perubahan itu benar-benar menurunkan domain dengan melihat hasil dari SELECT * FROM sys.dm_clr_appdomains;. Manis.
Granger