¡Hola, chicos!
En este artículo me gustaría compartir una situación que ocurrió durante el servicio de atención al cliente donde trabajo, es decir, otro caso real del día a día. Tuvimos una ocurrencia de base de datos que entró en modo sospechoso (nada que ver con esta publicación) y cuando analicé el registro de SQL Server para buscar más información sobre la base de datos que estaba marcada como sospechosa, vi muchas ocurrencias de error con el siguiente mensaje:

El proceso activado '[dbo].[sp_syspolicy_events_reader]' que se ejecuta en la cola 'msdb.dbo.syspolicy_event_queue' genera lo siguiente: 'No se puede ejecutar como principal de la base de datos porque el principal "##MS_PolicyEventProcessingLogin##" no existe, este tipo de principal no se puede suplantar o no tiene permiso.'

Ejemplo:

Entendiendo el problema

Al analizar el mensaje de error, podemos ver que probablemente se trate de un problema de permisos o que el usuario predeterminado del sistema “##MS_PolicyEventProcessingLogin##” esté huérfano. Como expliqué con más detalle en el artículo. Identificar y resolver usuarios huérfanos en SQL Server con sp_change_users_login, un usuario queda “huérfano” cuando pierde la asociación entre el inicio de sesión de la instancia y el usuario del banco, generalmente después de procesos de COPIA DE SEGURIDAD/RESTAURACIÓN o cuando se elimina el inicio de sesión de un usuario.

El inicio de sesión ##MS_PolicyEventProcessingLogin## se instala de forma predeterminada en SQL Server (deshabilitado), y es responsable de algunas tareas internas en la instancia, como leer eventos de Service Broker y administrar políticas.

Como podemos ver en los permisos de este usuario, tiene acceso de EJECUCIÓN al Procedimiento Almacenado sp_syspolicy_events_reader:

Si intentamos ejecutar este Procedimiento Almacenado como el usuario ##MS_PolicyEventProcessingLogin##, a través de un método IMPERSONATE (Para aprender más sobre IMPERSONATE, acceder a esta publicación), vemos el siguiente mensaje de error:

USE [msdb]
GO

EXECUTE AS USER = '##MS_PolicyEventProcessingLogin##' 
GO

Mensaje 15517, Nivel 16, Estado 1, Línea 1
No se puede ejecutar como principal de la base de datos porque el principal “##MS_PolicyEventProcessingLogin##” no existe, este tipo de principal no se puede suplantar o no tiene permiso.

Cuál es exactamente el mensaje de error con el que estamos tratando. Mmmmm..

Estos mensajes de error en el registro de SQL Server generalmente se generan en instancias que utilizan Service Broker para intercambiar mensajes (especialmente cuando hay MUCHOS registros de error con frecuencia) después de algún proceso de COPIA DE SEGURIDAD/RESTAURACIÓN de la base de datos msdb.

Si su instancia no utiliza Service Broker, incluso si este usuario está huérfano, probablemente no notará este problema.

Identificando el problema

Como expliqué en el artículo. Identificar y resolver usuarios huérfanos en SQL Server con sp_change_users_login, para identificar si el usuario ##MS_PolicyEventProcessingLogin## está huérfano, podemos utilizar la siguiente consulta:

SELECT
    A.[name] AS UserName,
    A.[sid] AS UserSID
FROM
    msdb.sys.database_principals A WITH(NOLOCK)
    LEFT JOIN sys.sql_logins B WITH(NOLOCK) ON A.[sid] = B.[sid]
WHERE
    B.[sid] IS NULL
    AND A.[name] = '##MS_PolicyEventProcessingLogin##'

Resultado:

Si la consulta devuelve alguna línea es porque el usuario ##MS_PolicyEventProcessingLogin## está huérfano y necesitaremos corregir este problema asociando el usuario de la base de datos msdb con el inicio de sesión correspondiente.

Simulando el problema

Si desea probar y/o simular este problema en su entorno, simplemente active Service Broker (active Database Mail, por ejemplo) y ejecute los siguientes comandos:

USE [master]
GO

CREATE LOGIN [teste] WITH PASSWORD = 'teste123', CHECK_EXPIRATION = OFF, CHECK_POLICY = OFF
GO

USE [msdb]
GO

ALTER USER [##MS_PolicyEventProcessingLogin##] WITH LOGIN = [teste]
GO

DROP LOGIN [teste]
GO


EXECUTE AS USER = '##MS_PolicyEventProcessingLogin##' 
GO

EXEC dbo.sp_syspolicy_events_reader
GO

REVERT
GO

Después de unos minutos, su registro de SQL Server probablemente se verá así:

Solucionando el problema

Ahora que entendemos la situación que está ocurriendo y hemos identificado que estos errores generados en el registro de SQL Server se deben a que el usuario ##MS_PolicyEventProcessingLogin## quedó huérfano, solucionemos este problema.

Para hacer esto, simplemente asocie el inicio de sesión con el usuario, con el siguiente comando:

USE [msdb]
GO

ALTER USER [##MS_PolicyEventProcessingLogin##] WITH LOGIN = [##MS_PolicyEventProcessingLogin##]
GO

También puedes usar sp_change_users_login para arreglar usuarios huérfanos:

USE [msdb]
GO

sys.sp_change_users_login 'Auto_Fix', '##MS_PolicyEventProcessingLogin##'
GO

Resultado:
La fila del usuario '##MS_PolicyEventProcessingLogin##' se solucionará actualizando su enlace de inicio de sesión a un inicio de sesión que ya existe.
El número de usuarios huérfanos solucionados al actualizar los usuarios fue 1.
La cantidad de usuarios huérfanos que se solucionó agregando nuevos inicios de sesión y luego actualizando a los usuarios fue 0.

Observación: Prefiero usar ALTER USER, ya que sp_change_users_login está marcado como obsoleto y puede eliminarse en futuras versiones de SQL Server.

Después de realizar estos cambios, los mensajes deberían haber dejado de aparecer en el registro de SQL Server. Como soy terco, quiero asegurarme de que realmente esté funcionando en lugar de esperar a que desaparezcan los mensajes de error:

Ahora estoy tranquilo. 🙂

Espero que hayas disfrutado este artículo y ¡hasta la próxima!
¡Gran abrazo!