Además de reiniciar SQL Server, ¿hay alguna forma de forzar el reinicio del dominio de aplicación SQLCLR?


11

Quiero forzar el reinicio del AppDomain que SQLCLR está utilizando. ¿Cómo puedo hacer eso además de reiniciar la instancia de SQL Server?


No estoy seguro si recibe notificaciones sobre actualizaciones de respuestas, pero actualicé mi respuesta con un método aún más fácil :).
Solomon Rutzky

Respuestas:


6

Sé que esto es un poco brutal, pero ¿qué hay de deshabilitar el CLR y volver a habilitarlo?

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
Un detalle importante sobre este método es que funciona cuando se ejecuta contra una base de datos STANDBY (solo lectura); todos los otros métodos que he probado no lo hacen. Necesitaba esto porque una actualización de un ensamblaje CLR se propagó de manera normal a través del envío de registros a un catálogo STANDBY, pero el AppDomain no se volvió a cargar, por lo que continuó ejecutando el código de la versión anterior del .dll durante aproximadamente un día.
Granger

@Granger muy interesante y bueno saber :). Sin embargo, consideraría que es un error dentro de SQL Server. Es posible que desee informar a través del sitio de Connect: connect.microsoft.com/SQLServer/Feedback
Solomon Rutzky

1
@srutzky - Gracias por la sugerencia; Espero que cierren el informe como "No se solucionará". La configuración es para todo el servidor, no por catálogo (al igual que 'desencadenadores anidados', 'nivel de acceso de flujo de archivos', etc.). Esa es la lata de gusanos que intentaría abrir.
Granger

@Granger (y Max): no tenía claro lo que decía que pensaba que era un error. No estaba diciendo que restablecer la configuración "CLR habilitado" que causaba la descarga era un error. Estaba diciendo que la ALTER ASSEMBLYpropagación a través del envío de registros que no volvió a cargar (o al menos no descargó) el dominio de la aplicación fue el error. De cualquier manera, encontré un método aún más fácil que agregué a mi respuesta aquí. Si tuviera la capacidad de probar este nuevo método, sería genial, ya que tengo mucha curiosidad por ver si funciona en el escenario de envío de registros que describió.
Solomon Rutzky

8

Hay una solución más elegante que no afectará a todos los demás conjuntos: simplemente cambie el PERMISSION_SET de uno de los conjuntos en el dominio de la aplicación (los dominios de la aplicación son por usuario).

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

Solo recuerde que deberá volver a establecer el PERMISSION_SET a lo que era. Además, debe acceder a un método en el ensamblaje antes de cambiar el PERMISSION_SET para descargarlo; cambiar un ensamblaje que no está cargado actualmente en un dominio de aplicación que está activo, pero con otro ensamblaje, no tiene ningún efecto en el dominio de la aplicación (los dominios de aplicación son por DB, por usuario, no por ensamblaje).


ACTUALIZACIÓN
El método descrito anteriormente es el enfoque más detallado donde solo descargará ese dominio de aplicación. Pero sí requiere que el ensamblaje se pueda establecer en uno de los otros dos niveles. Para conjuntos marcados como SAFEsolo será posible si

  • la base de datos se establece en TRUSTWORTHY ON, o
  • el ensamblado se firma y existe un inicio de sesión, basado en una clave asimétrica que se basa en la misma firma que el ensamblado, existe y se le ha otorgado EXTERNAL ACCESS ASSEMBLYel UNSAFE ASSEMBLYpermiso o el permiso

En este caso, simplemente puede cambiar la TRUSTWORTHYconfiguración ONe inmediatamente volver de OFFnuevo y eso descargará todos los dominios de aplicaciones en esa base de datos en particular:

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

Si de todos modos solo tiene un dominio de aplicación en la base de datos (y sospecho que este es el caso el 95% o más del tiempo), entonces los dos métodos descritos aquí tienen el mismo efecto neto. Y en esa situación, el ALTER DATABASEmétodo parece más simple, ya que no requiere especificar un nombre de objeto en particular ni requiere saber cuál era el original PERMISSION_SET.

TAMBIÉN, si solo tiene un único dominio de aplicación, entonces el ALTER DATABASEmétodo es más simple incluso en el caso de que la base de datos ya esté configurada TRUSTWORTHY ONo haya configurado el inicio de sesión de base de clave con el permiso apropiado. Si está utilizando un inicio de sesión basado en clave entonces se puede establecer TRUSTWORTHYque ONa continuación, OFFde nuevo como se mencionó anteriormente. Pero si ya lo TRUSTWORTHYconfiguró ON, simplemente inviértalo y configúrelo OFFy luego vuelva inmediatamente a ON:

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

1
El enfoque actualizado funciona en un catálogo de base de datos STANDBY (READ_ONLY). SQL Server me permitió cambiar la configuración "CONFIABLE" y luego restaurarla a lo que era antes. Verifiqué que el cambio realmente descargó el dominio mirando el resultado de SELECT * FROM sys.dm_clr_appdomains;. Dulce.
Granger
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.