Como executar tarefas ao iniciar o SQL Server ?

Boa Noite Pessoal,

Hoje no fórum do MSDN eu vi uma dúvida bem interessante. A dúvida perguntava sobre uma forma de apagar registros de tabelas sempre que o servidor do SQL Server fosse reiniciado. Do ponto de vista do sistema operacional é possível configurar alguns aplicativos para iniciar automaticamente. Não sei se é possível configurar que algum executável seja disparado logo após algum serviço ser iniciado, mas confesso que essas alternativas soam não seguras. Algum antivírus ou o próprio Windows Defender podem interpretar isso como uma tentativa de ataque.

Desconsiderando as alternativas do sistema operacional é possível configurar o SQL Server para que uma Stored Procedure seja disparada logo após o serviço ser iniciado. Isso permitiria atender à necessidade anterior. Disparar uma stored procedure quando o SQL Server inicia não é o mesmo que disparar alguma ação quando o Windows inicia. O SQL Server é um serviço do Windows e não necessariamente irá iniciar apenas porque o Windows iniciou. Mesmo configurado para iniciar automaticamente existe a possibilidade do serviço não subir. Só que se a necessidade é apagar registros de tabelas, fatalmente o SQL Server deverá estar iniciado e se o procedimento a ser executado envolve o SQL Server é preciso que esse serviço esteja ativo. Se a ação necessária envolve o SQL Server, colocar uma stored procedure para disparar é uma alternativa válida. Esse tipo de Stored Procedure é conhecido como startup Stored Procedure. Os scripts a seguir mostram sua utilização xcluir todos os registros mais antigos que seis meses toda vez que o SQL Server for iniciado.

Inicialmente é criado um banco de dados com alguns registros para teste. A data em que esse artigo é escrito é 19/05/2009 e tendo-se essa data como data base, alguns dos registros abaixo terão mais de seis e outros não.

— Cria um dados
CREATE DATABASE BD

— Muda o contexto do banco de dados
USE BD;

— Cria uma tabela no banco de dados
CREATE TABLE Lancamentos (
    IDLancamento INT IDENTITY(1,1),
    Data SMALLDATETIME, Valor SMALLMONEY)

— Insere alguns registros
INSERT INTO Lancamentos (Data, Valor) VALUES (‘20080515’,5200)
INSERT INTO Lancamentos (Data, Valor) VALUES (‘20081007’,2300)
INSERT INTO Lancamentos (Data, Valor) VALUES (‘20081118’,1200)
INSERT INTO Lancamentos (Data, Valor) VALUES (‘20090223’,7900)
INSERT INTO Lancamentos (Data, Valor) VALUES (‘20090520’,8100)

O próximo passo é criar a stored procedure que irá excluir os registros mais antigos que seis meses. O SQL Server exige que stored procedures do tipo startup sejam criadas no banco de dados MASTER e que tenham a propriedade startup configurada para true.

— Muda o contexto do banco de dados para o MASTER
USE MASTER
GO

— Cria uma stored procedure no MASTER
— Essa SP exclui Lancamentos anteriores a seis meses

CREATE PROCEDURE UspExcluirRegistrosAntigos
AS
DELETE FROM
BD.dbo.Lancamentos
WHERE Data <= DateAdd(M,-6,GETDATE())
GO

— Marca a SP para disparar automaticamente quando o SQL Server iniciar
EXEC sp_procoption ‘UspExcluirRegistrosAntigos’, ‘startup’, ‘true’

Aparentemente está tudo pronto para que a stored procedure seja disparada logo após o serviço iniciar. Seria realmente mais fácil se apenas essas ações fossem necessárias, mas seria também igualmente perigoso. Disparar uma stored procedure sempre que o SQL Server iniciar representa de alguma forma "baixar" a segurança. Uma stored procedure que dispare toda vez que o SQL Server iniciar poderia ser utilizada para ações que prejudicassem os bancos de dados, o sistema operacional ou até a rede dependendo da conta de serviço do SQL Server. Seguindo a iniciativa "Secure By Default", por padrão o SQL Server não dispara stored procedures startup automaticamente. É preciso que ele seja configurado para esse fim (admitindo-se que nesse caso os riscos são conhecidos).

— Configura o SQL Server para permitir a execução de SPs Startup
EXEC sp_configure ‘Show Advanced Options’,1
RECONFIGURE WITH OVERRIDE

EXEC sp_configure ‘scan for startup procs’,1
RECONFIGURE WITH OVERRIDE

Se o serviço for reiniciado, pode-se notar que a stored procedure fez a exclusão conforme o previsto.

— Muda o contexto do banco de dados
USE BD;

— Consulta os lançamentos
SELECT IDLancamento, Data, Valor FROM Lancamentos

Embora a execução funcione, algumas dúvidas podem surgir acerca da execução. Algumas recomendações importantes:

  • A conta que executa a stored procedure é a conta de serviço e portanto é SysAdmin e pode acessar recursos do sistema operacional
  • Se algum erro ocorrer com a Stored Procedure, esses erros serão gravados no ErrorLog do SQL Server
  • Não codifique eventos externos ao SQL Server. Se essa é a necessidade use o agendador de tarefas, o autoexec.bat ou o WMI
  • Se possível evite o uso desse recurso no desenvolvimento de aplicações, pois, nem um procedimento dessa natureza é tolerável

O uso de procedures startup pode ser muito útil para DBAs. Com sua utilização é possível por exemplo atualizar registros de tabelas de controle, logar o horário que SQL Server foi iniciado entre outras ações administrativas. A partir do momento que esse recurso é utilizado é necessário redobrar a atenção para que stored procedures indesejadas não sejam criadas e disparem automaticamente.

[ ]s,

Gustavo

4 Respostas para “Como executar tarefas ao iniciar o SQL Server ?

  1. Muito boa matéria Maia.Apesar de já ter lido sobre este tipo de stored procedure, confesso que nunca as utilizei.Vou fazer alguns testes, apenas para ter como uma carta na manga em uma necessidade eventual. hehehe[ ]s.

  2. Amigos DBAs, primeiro farei um alerta e depois agraciarei a utilização desse recurso.Após realizarmos todas as alterações que nosso amigo Gustavo descreveu neste artigo para que uma procedure seja executada quando o serviço do SQL Server for iniciado automaticamente, cabe dizer que caso esta procedure por algum motivo apresente um erro durante sua execução, o serviço do SQL Server ficará intermitente.Passei por essa experiência em 2003. -Apos reinicializar um servidor o serviço do SQL Server subiu e ficou no ar durante 5 minutos até cair novamente, o serviço estava configurado para reiniciar em caso de falha e esse comportamento de ficar online e indisponível durou 20 minutos. Analisando os logs, percebi que tinha uma startup procedure que executava um script que estava com problema de overflow, esse overflow fez com que o serviço ficasse intermitente e enquanto a procedure não foi removida da inicialização do SQL o problema não foi resolvido.A parte boa é que neste mesmo ambiente utilizavamos cargas de grandes arquivos através de operações de bulk insert. Para que essas cargas funcionem é necessário que o usuário GUEST tenha permissão na database role DB_OWNER do TEMPDB. O problema é que ao reiniciar o serviço do SQL ou o servidor o usuário GUEST perdia essa permissão.Para resolver o problema criamos uma startup procedure e toda vez que acontece um failover ou restart do serviço ela atribui novamente as permissões necessárias para que as operações de bulk insert ocorram sem problema.Resumindo, a utilização desse recurso é bem vinda, mas deve-se testar bastante o código a ser implementado para que não ocorra indisponibilidade no serviço.[]´s

  3. Oi Wagner,Muito bem lembrado. Esqueci de incluir esse detalhezinho no artigo. A verdade é que stored procedures startup são tão perigosas quanto as triggers de logon, ou seja, um erro e a indisponibilidade é certa. Se a SP tiver problemas, o SQL Server terá problemas. Não incluí no artigo, mas se isso acontecer, o SQL Server terá que ser iniciado via Prompt ou o modo mínimo (-f) ou ainda com o Trace Flag 4022. Qualquer uma dessas configurações fará com que as procedures não sejam disparadas.Abs,

  4. Oi Thiago,Como pode ver há uma boa utilização para essa procedure (a citada pelo Wagner). Você pode ainda utilizá-la para remover automaticamente os usuários indesejados. Assim, mesmo que alguém coloque uma conta indesejada, toda vez que o SQL Server subir, a conta será removida.Abs,

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s