Em uma instância do SQL Server 2014 com RAM suficiente e discos rápidos, existem mais de 160 usuários com acesso a um banco de dados. Por algum motivo desconhecido para mim, a execução do comando DROP USER [username]
neste banco de dados leva até 5 segundos por usuário.
Remapear usuários para logins e restaurar suas permissões é muito rápido.
No contexto de atualização dos bancos de dados DEV da produção, tenho que descartar e recriar todos os usuários do banco de dados. Portanto, é necessário descartar os usuários do banco de dados e recriá-los.
Como faço para acelerar o DROP USER
comando?
Lembre-se, tenho que executá-lo 160 vezes para a instância sobre a qual estou escrevendo.
Este é o SQL que estou usando:
DECLARE drop_user_cur CURSOR FOR
SELECT name FROM #drop_users
OPEN drop_user_cur
FETCH NEXT FROM drop_user_cur INTO @user
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql = 'use [' + @db_name + '] DROP USER [' + @user + ']'
BEGIN TRY
print @sql
EXECUTE(@sql)
END TRY
BEGIN CATCH
print 'ERREUR : ' + @sql
END CATCH
FETCH NEXT FROM drop_user_cur INTO @user
END
CLOSE drop_user_cur
DEALLOCATE drop_user_cur
O problema não está vindo do cursor; é o real DROP USER
que está demorando até 5 segundos.
Usando sp_whoisactive
, o wait_type é NULL
.
Não preste atenção à duração, o DROP
e CREATE USER
estava sendo executado em um WHILE
loop, e é por isso que está dizendo mais de um minuto.
O Profiler mostra mais de 125.000 leituras para executar DROP USER
.
O Service Broker não está ativado.
A solução para esse problema foi ativar o service broker no banco de dados.
Depois de habilitar o service broker para o banco de dados, a queda de usuários foi praticamente instantânea.
Kin perguntou se o corretor de serviços estava habilitado em um comentário anterior que me enviou procurando na direção certa.
esta não é uma resposta para a pergunta, mas um argumento para descartá-la completamente.
Se entendi bem seu comentário:
seu objetivo é copiar os dados de produção para um sistema de desenvolvimento e fazê-lo funcionar com a mesma permissão do sistema de produção, usando os mesmos nomes de usuário .
O caminho mais rápido é clonar logins sql do sistema de produção para o sistema de desenvolvimento usando o procedimento descrito por ms neste artigo do KB .
com o procedimento definido por ms, o resultado é que você pode restaurar os bancos de dados em seu servidor dev e a permissão está funcionando sem alterações.
Eu usei com sucesso o procedimento acima mencionado para copiar um ambiente de produção sql 2005 para ambos os ambientes test & dev sql 2012.
Depois de clonar os usuários, uma simples restauração do banco de dados me levou a um par de novos sistemas totalmente funcionais com dados atualizados.
A grande vantagem dessa solução é que, para atualizar os dados de desenvolvimento, basta restaurar o banco de dados de produção e pronto; você terá que ajustar referências, sinônimos e afins, mas as permissões não serão quebradas.
Aqui está o código do artigo, apenas para referência, mas consulte o artigo que contém comentários e detalhes sobre compatibilidade com versões antigas do sql, detalhes de criptografia de senha e outras informações que podem evitar dores de cabeça ao transferir os logins entre os servidores:
Um cursor semelhante a este deve funcionar